还是Go 为了伟大的未来

今天,还是想讲讲Go

我觉得还没讲够,哈哈哈

其实,是想把框架再清晰些,因为上一篇框架没能引入goroutine(协程),感觉比较遗憾

下边,我就用上goroutine,但这里的协程仅是为了演示,没有任何提升处理效率的能力,切记

我主要是为了下篇博文做引子而已,哪里是讲web服务器的效率问题

记住,我之前的博文,都是为了把客户端的功能服务化,换句话说,没有效率不效率,并发连接数高低之说,如果一件事要一天做完,不好意思,你也必须等一天!就这么回事。人们常说的百万级,数亿级web服务,跟我说的就不是一回事

//package main

package main

import (
"Enroll_lib"
)

func server(pw32 *Enroll_lib.Win32_handle, X []string) string {

if 1<=len(X) {
if X[0]=="getVersion" {
version := pw32.GetVersion()
var ret string = ""
ret += "{"
ret += ""result""
ret += ":"
ret += """
ret += version
ret += """
ret += "}"
return ret
}
}

return ""
}

package main

import (
"fmt"
"os"
"net/http"
"Enroll_lib"
"strconv"
//"encoding/json"
)

func routine(c chan string, X []string) {
var w32_handle Enroll_lib.Win32_handle
var pw32 *Enroll_lib.Win32_handle = &w32_handle

res := pw32.LoadLib()
if !res {
fmt.Println("Load library failure")
}
res = pw32.GetHandle()
if !res {
fmt.Println("GetHandle failure")
}

var ret string
ret = server(pw32, X)

pw32.ReleaseHandle()
pw32.FreeLib()

c <- ret
}

func entry(res http.ResponseWriter, req *http.Request) {
req.ParseForm()
//fmt.Println("post KV count: ", len(req.PostForm))
count := len(req.PostForm)
if 1<=count {
var arr []string
method := req.PostFormValue("method")
arr = append(arr, method)
for i:=1; i<count; i++ {
arr = append(arr, req.PostFormValue("param"+strconv.Itoa(i)))
}
var c chan string
c = make(chan string)
go routine(c, arr)
ret := <- c
fmt.Fprintf(res, ret)
} else {
fmt.Fprintf(res, "RESTful web API has nothing to do, invalid request ")
}
}

func main() {
Port := "8086"
IsHttp := true
arg_num := len(os.Args)
if 2<=arg_num {
Port = os.Args[1]
}
if 3<=arg_num {
if os.Args[2]=="true" {
IsHttp = true
} else {
IsHttp = false
}
}
fmt.Printf("server is http %t ", IsHttp)
fmt.Println("server listens at ", Port)

http.HandleFunc("/", entry)

var err error
if IsHttp {
err = http.ListenAndServe(":"+Port, nil)
} else {
err = http.ListenAndServeTLS(":"+Port, "server.crt", "server.key", nil)
}
if err != nil {
fmt.Println("Server failure /// ", err)
}

fmt.Println("quit")
}

//package Enroll_lib

package Enroll_lib

import(
"fmt"
"syscall"
"C"
"unsafe"
)

type Win32_handle struct {
handle syscall.Handle
c_enroll_handle uintptr
c_lib_handle uintptr
err error
}

func (h *Win32_handle) LoadLib() bool {
h.handle, h.err = syscall.LoadLibrary("Enroll.dll")
if h.err!=nil {
fmt.Println("Enroll.dll not found")
return false
}

return true
}

func (h *Win32_handle) FreeLib() {
syscall.FreeLibrary(h.handle)
}

func (h *Win32_handle) GetHandle() bool{
getHandle, err := syscall.GetProcAddress(h.handle, "getHandle")
if err!=nil {
fmt.Println("getHandle not found")
return false
}
r,_,retstr := syscall.Syscall(uintptr(getHandle), 3, uintptr(unsafe.Pointer(&h.c_enroll_handle)),
uintptr(unsafe.Pointer(&h.c_lib_handle)),
0)
if false {
fmt.Println(retstr)
}
if r==0 {
fmt.Println("syscall failuer at getHandle")
return false
}

return true
}

func (h *Win32_handle) ReleaseHandle() {
releaseHandle, err := syscall.GetProcAddress(h.handle, "releaseHandle")
if err!=nil {
fmt.Println("releaseHandle not found")
}
r,_,retstr := syscall.Syscall(uintptr(releaseHandle), 3, uintptr(unsafe.Pointer(&h.c_enroll_handle)),
uintptr(unsafe.Pointer(&h.c_lib_handle)),
0)
if false {
fmt.Println(retstr)
}
if r==0 {
fmt.Println("syscall failuer at releaseHandle")
}
}

func (h *Win32_handle) FreeMem(p *C.char) {
freeMem, err := syscall.GetProcAddress(h.handle, "freeMem")
if err!=nil {
fmt.Println("freeMem not found")
}
r,_,retstr := syscall.Syscall(uintptr(freeMem), 3, uintptr(unsafe.Pointer(&h.c_enroll_handle)),
uintptr(unsafe.Pointer(&h.c_lib_handle)),
uintptr(unsafe.Pointer(&p)))
if false {
fmt.Println(retstr)
}
if r==0 {
fmt.Println("syscall failuer at freeMem")
}
}

func (h *Win32_handle) GetVersion() string {
getVersion, err := syscall.GetProcAddress(h.handle, "getVersion")
if err!=nil {
fmt.Println("getVersionm not found")
}
var p *C.char
r,_,retstr := syscall.Syscall(uintptr(getVersion), 3, uintptr(unsafe.Pointer(&h.c_enroll_handle)),
uintptr(unsafe.Pointer(&h.c_lib_handle)),
uintptr(unsafe.Pointer(&p)))
if false {
fmt.Println(retstr)
}
if r==0 {
fmt.Println("syscall failure at getVersion")
}

defer h.FreeMem(p)

return C.GoString(p)
}

Finally:

我只想提醒两点:

1. 不要试图把res http.ResponseWriter, req *http.Request传给协程去接着干,http不能跨协程

  你希望的如此简易高并发,还是在此歇菜了吧,哈哈哈

2.web服务的HTTP请求-应答本身就不能并发,请求干的具体事务是可以并发执行的,这一点是web的本质,跟你用何种语言无关

  天下难点是一致的,任何语言都是相通一致的

原文地址:https://www.cnblogs.com/woodzcl/p/7601059.html