还是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\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 为了伟大的未来的更多相关文章
- CSS的未来
		
仅供参考 前言 完成<CSS核心技术与实战>这本书,已有一个多月了,而这篇文章原本是打算写在那本书里面的,但本章讲解的内容,毕竟属于CSS未来的范畴,而这一切都还不能够确定下来,所以这一章 ...
 - 从中间件的历史来看移动App开发的未来
		
在移动开发领域我们发现一个很奇怪的现象:普通菜鸟新手经过3个月的培训就可以拿到 8K 甚至上万的工作:在北京稍微有点工作经验的 iOS 开发,就要求 2 万一个月的工资.不知道大家是否想过:移动应用开 ...
 - 展望未来:使用 PostCSS 和 cssnext 书写 CSS
		
原文链接:A look into writing future CSS with PostCSS and cssnext 译者:nzbin 像twitter,google,bbc使用的一样,我打算看一 ...
 - 代码的坏味道(17)——夸夸其谈未来性(Speculative Generality)
		
坏味道--夸夸其谈未来性(Speculative Generality) 特征 存在未被使用的类.函数.字段或参数. 问题原因 有时,代码仅仅为了支持未来的特性而产生,然而却一直未实现.结果,代码变得 ...
 - 如何理解DT将是未来IT的转型之路?
		
如今的IT面临着内忧外患的挑战. 一方面,企业多多少少都建立了信息化,有些企业或集团甚至会有数几十个分公司,包含直销.代理.零售以及第三方物流等多种业态.越是复杂的业务,信息化建设越困难,比如运用大量 ...
 - 面向未来的友好设计:Future Friendly
		
一年前翻译了本文的一部分,最近终于翻译完成.虽然此设计思想的提出已经好几年了,但是还是觉得应该在国内推广一下,让大家知道“内容策略”,“移动优先”,“响应式设计”,“原子设计”等设计思想和技术的根源. ...
 - 【流量劫持】SSLStrip 的未来 —— HTTPS 前端劫持
		
前言 在之前介绍的流量劫持文章里,曾提到一种『HTTPS 向下降级』的方案 -- 将页面中的 HTTPS 超链接全都替换成 HTTP 版本,让用户始终以明文的形式进行通信. 看到这,也许大家都会想到一 ...
 - HTPC家庭娱乐和XBOX未来发展畅想<另:创业工作机会>
		
微软中国在上海举办新闻发布会,正式宣布Xbox One将于9月23日在中国开始销售,定价3699元起.这款早在2001年就发布的电视游戏机终于在经历了14年的等待后,进军中国大陆市场.此次Xbox O ...
 - 2015游戏蛮牛——蛮牛杯第四届开发者大赛 创见VR未来开启报名
		
蛮牛杯启动了,大家开始报名! http://cup.manew.com/ 这不是一篇普通的通稿,别着急忽略它.它是一篇可以让你梦想变现的通稿! 从某一天开始,游戏蛮牛就立志要为开发者服务,我们深知这一 ...
 - 来,一起让我们越来越懒,面向CSS、JS未来编程。(9.28已更新)
		
2016.10.29更新 本文存在大量的错误,仅供参考. 不知不觉在前端领域马上一个年头就要过去了,然而再看看自己的代码,果然够烂,那么为什么代码一直没有用面向对象的思维去写CSS呢?首先有两点:一点 ...
 
随机推荐
- svn异常:subversion.javahl.ClientException
			
使用svn时出现异常: INFO [org.netbeans.modules.subversion]: org.apache.subversion.javahl.ClientException: Pr ...
 - 分布式文件系统HDFS,大数据存储实战(一)
			
本文进行了以下工作: OS中建立了两个文件,文件中保存了几组单词. 把这两个文件导入了hadoop自己的文件系统. 介绍删除已导入hadoop的文件和目录的方法,以便万一发生错误时使用. 使用列表命令 ...
 - [No000018F]Vim自动缩进配置、原理和tab键替换空格-Vim使用技巧(4)
			
一.Vim缩进介绍 在没有设置Vim自动缩进的条件下,可以手动使用Vim命令对特定行进行缩进处理.在Vim插入模式下,按下 Tab 键时默认会输入一个制表符,可通过Vim配置项将 Tab 替换为空格, ...
 - springboot程序无法访问静态资源
			
今天开发遇到了一个很奇葩的错误,再spngboot程序成功运行后发现无法访问再resouces/static下的静态资源,通过rul访问总是404,原因最终锁定在某配置类的一个标签上: @Enable ...
 - 静态方法中只允许访问静态数据,那么,如何在静态方法中访问类的实例成员(即没有附加static关键字的字段或方法)?
			
package test.two; public class jingtaihanshu { int x = 3; static int y = 4; public static void Meth ...
 - linux 背单词
			
命令缩写: ls:list(列出目录内容) cd:Change Directory(改变目录) su:switch user 切换用户rpm:redhat package manager 红帽子打包管 ...
 - SQL之层次查询
			
层次查询是一种确定数据行间关系的一种操作手段.层次查询遍历的是一个树形结构.基本语法如下,以下语法嵌入到标准SQL中即可达到层次查询的目的: level,... ...[注释:伪列,用于select子 ...
 - 使用FFmpeg常见问题
			
使用FFmpeg常见问题 https://blog.csdn.net/willib/article/details/52530328 https://blog.csdn.net/nogodoss/ar ...
 - vsftp设置不同用户登录ftp的根目录不同
			
创建三个用户 [root@SHM-Storage-EF ~]# useradd kids [root@SHM-Storage-EF ~]# useradd mini [root@SHM-Storage ...
 - iphone及ipad屏幕尺寸参考
			
初代iPhone 2007年,初代iPhone发布,屏幕的宽高是 320 x 480 像素.下文也是按照宽度,高度的顺序排列.这个分辨率一直到iPhone 3GS也保持不变.那时编写iOS的App(应 ...