在Google官方维护的code.google.com\p\go.net\websocket包中的server.go文件中,曾经有这么一段描述:
//Handler is a simple interface to a WebSocket browser client.
// It checks if Origin header is valid URL by default.
// You might want to verify websocket.Conn.Config().Origin in the func.
// If you use Server instead of Handler,you could call websocket.Origin and
// check the origin in your Handshake func.So,if you want to accept
// non-browser client,which doesn't send Origin header,you could use Server
//. that doesn't check origin in its Handshake.
这里说到,Handler是一个针对Websocket浏览器客户端的简单接口,默认情况下,Handler会检查Http请求的头文件的Origin是否是一个有效的值。最后说到,如果你想接收一个并不带有Origin字段信息的非浏览器客户端发送的websocket请求,你应该使用Server,使用Server不会在Websocket握手时对Origin进行检查。
也许我们会问,什么是浏览器客户端,而什么又是非浏览器客户端,笔者对此研究的不深,只是在开发中发现,在进行go web编程时,由于go本身可以使用template模板向用户推送页面,比如用户在客户端输入127.0.0.1:9000,服务器收到这个请求,就会发送网站的首页给用户(这里假设127.0.0.1:9000的/,这个路由对应一个首页的get请求)。笔者认为凡是通过go编写的web服务端程序推送给用户的这个网页就是浏览器客户端。而除此之外的其他的非推送的网页请求,以及一些手机(andriod、ios的手机)客户端发送的请求都属于非浏览器客户端。
那我们又会问,如果是浏览器客户端,该如何使用Handler,而非浏览器客户端,该如何使用Server呢?下面就简单举例说一下:
先说浏览器客户端的监听websocket编程的写法,代码实例为:
package main
import (
)
var connid int
var conns *list.List
func ChatroomServer(ws *websocket.Conn) {
}
func SendMessage(self *list.Element,data string) {
}
func Client(w http.ResponseWriter,r *http.Request) {
<html> <head> <Meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>golang websocket chatroom</title> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> <script> var ws = new WebSocket("ws://127.0.0.1:6611/chatroom"); ws.onopen = function(e){ console.log("onopen"); console.dir(e); }; ws.onmessage = function(e){ console.log("onmessage"); console.dir(e); $('#log').append('<p>'+e.data+'<p>'); $('#log').get(0).scrollTop = $('#log').get(0).scrollHeight; }; ws.onclose = function(e){ console.log("onclose"); console.dir(e); }; ws.onerror = function(e){ console.log("onerror"); console.dir(e); }; $(function(){ $('#msgform').submit(function(){ ws.send($('#msg').val()+"\n"); $('#log').append('<p style="color:red;">My > '+$('#msg').val()+'<p>'); $('#log').get(0).scrollTop = $('#log').get(0).scrollHeight; $('#msg').val(''); return false; }); }); </script> </head> <body> <div id="log" style="height: 300px;overflow-y: scroll;border: 1px solid #CCC;"></div> <div> <form id="msgform"> <input type="text" id="msg" size="60" /> </form> </div> </body> </html>`
io.WriteString(w,html)
}
func main() {
}
以上是一个完整的针对浏览器客户端发送websocket的服务器代码,可以看到,当用户请求路由为/时,服务器推送一个页面给用户,这个页面含有websocket套接字,然后收到这个页面的用户,就可以在这个页面是输入信息发往后台,发送时使用的就是websocket。main函数中展示了如何使用websocket.Handler.
下面说一下非浏览器客户端的写法,这里只修改了main函数,为了能够同时监听http请求和websocket请求,与上面不同,这里使用了多协程的方式实现,同时这里的websocket监听无须路由,所有的websocket,无论路由是多少,都将被监听到,代码如下:
}
完结