今天,还是想讲讲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\n")
}
}

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\n", 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的本质,跟你用何种语言无关

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

还是Go 为了伟大的未来的更多相关文章

  1. CSS的未来

    仅供参考 前言 完成<CSS核心技术与实战>这本书,已有一个多月了,而这篇文章原本是打算写在那本书里面的,但本章讲解的内容,毕竟属于CSS未来的范畴,而这一切都还不能够确定下来,所以这一章 ...

  2. 从中间件的历史来看移动App开发的未来

    在移动开发领域我们发现一个很奇怪的现象:普通菜鸟新手经过3个月的培训就可以拿到 8K 甚至上万的工作:在北京稍微有点工作经验的 iOS 开发,就要求 2 万一个月的工资.不知道大家是否想过:移动应用开 ...

  3. 展望未来:使用 PostCSS 和 cssnext 书写 CSS

    原文链接:A look into writing future CSS with PostCSS and cssnext 译者:nzbin 像twitter,google,bbc使用的一样,我打算看一 ...

  4. 代码的坏味道(17)——夸夸其谈未来性(Speculative Generality)

    坏味道--夸夸其谈未来性(Speculative Generality) 特征 存在未被使用的类.函数.字段或参数. 问题原因 有时,代码仅仅为了支持未来的特性而产生,然而却一直未实现.结果,代码变得 ...

  5. 如何理解DT将是未来IT的转型之路?

    如今的IT面临着内忧外患的挑战. 一方面,企业多多少少都建立了信息化,有些企业或集团甚至会有数几十个分公司,包含直销.代理.零售以及第三方物流等多种业态.越是复杂的业务,信息化建设越困难,比如运用大量 ...

  6. 面向未来的友好设计:Future Friendly

    一年前翻译了本文的一部分,最近终于翻译完成.虽然此设计思想的提出已经好几年了,但是还是觉得应该在国内推广一下,让大家知道“内容策略”,“移动优先”,“响应式设计”,“原子设计”等设计思想和技术的根源. ...

  7. 【流量劫持】SSLStrip 的未来 —— HTTPS 前端劫持

    前言 在之前介绍的流量劫持文章里,曾提到一种『HTTPS 向下降级』的方案 -- 将页面中的 HTTPS 超链接全都替换成 HTTP 版本,让用户始终以明文的形式进行通信. 看到这,也许大家都会想到一 ...

  8. HTPC家庭娱乐和XBOX未来发展畅想<另:创业工作机会>

    微软中国在上海举办新闻发布会,正式宣布Xbox One将于9月23日在中国开始销售,定价3699元起.这款早在2001年就发布的电视游戏机终于在经历了14年的等待后,进军中国大陆市场.此次Xbox O ...

  9. 2015游戏蛮牛——蛮牛杯第四届开发者大赛 创见VR未来开启报名

    蛮牛杯启动了,大家开始报名! http://cup.manew.com/ 这不是一篇普通的通稿,别着急忽略它.它是一篇可以让你梦想变现的通稿! 从某一天开始,游戏蛮牛就立志要为开发者服务,我们深知这一 ...

  10. 来,一起让我们越来越懒,面向CSS、JS未来编程。(9.28已更新)

    2016.10.29更新 本文存在大量的错误,仅供参考. 不知不觉在前端领域马上一个年头就要过去了,然而再看看自己的代码,果然够烂,那么为什么代码一直没有用面向对象的思维去写CSS呢?首先有两点:一点 ...

随机推荐

  1. AtCoder Beginner Contest 070|Elena|8.12|#471

    打了场beginner的AtCoder,也是我第一次打AtCoder,虽然AK了,但是由于手速慢+撒比,才#471… 比赛链接:https://beta.atcoder.jp/contests/abc ...

  2. *** FATAL ERROR L250: CODE SIZE LIMIT IN RESTRICTED VERSION EXCEEDED

    *** FATAL ERROR L250: CODE SIZE LIMIT IN RESTRICTED VERSION EXCEEDED 在软件已经执行破解仍然出现,是因为工程是破解前建立的,要先执行 ...

  3. spark application提交应用的两种方式

    bin/spark-submit --help ... ... --deploy-mode DEPLOY_MODE   Whether to launch the driver program loc ...

  4. Hystrix在项目中实践

    Hystrix在项目中实践 https://mp.weixin.qq.com/s/4Fg0COnWRB3rRWfxbJt7gA

  5. day5_集合

    集合也是一种数据类型,一个类似列表东西,它的特点是无序的,不重复的,也就是说集合中是没有重复的数据 集合的作用: 1.它可以把一个列表中重复的数据去掉,而不需要你再写判断---天生去重 2.可以做关系 ...

  6. 洛谷P3158 放棋子 [CQOI2011] dp+数论

    正解:dp+数论 解题报告: 传送门! 考虑对每种颜色的棋子单独考虑鸭,那显然有,当某一行或某一列已经被占据的时候,那一行/一列就不能再放别的颜色的棋子了,相当于直接把那一行/一列直接消了 显然就能考 ...

  7. 关于linux特殊含义的转义符\033

    格式: echo -e "\033[字背景颜色;字体颜色m字符串\033[0m" 例如: echo -e "\033[41;36m something here \033 ...

  8. 并查集——合作网络D306

    合作网络D306             运行时间限制:1000ms: 运行空间限制:51200KB: 试题描述 有n个结点,初始时每个结点的父结点都不存在.你的任务是执行若干次Set操作和Query ...

  9. 王者荣耀里拿个王者有啥了不起,有胆就来挑战一下ApsaraCache源码

    王者荣耀大家估计都玩的很溜吧,撸完代码开一局,只要不遇到个猪队友,拿个鲁班后羿估计你们都能爆掉对手的塔吧.大神们打个排位赛拿个王者就和吃饭夹菜一样简单... But...你们玩过Redis和Memca ...

  10. oracle中is和as的区别

    在存储过程(PROCEDURE)和函数(FUNCTION)中没有区别:在视图(VIEW)中只能用AS不能用IS:在游标(CURSOR)中只能用IS不能用AS.