我们先写一个最简单的go http服务
- package main
-
- import (
- "net/http"
- )
-
- func main() {
- http.HandleFunc("/",func(w http.ResponseWriter,r *http.Request) {
- w.Write([]byte("hello world"))
- })
- http.ListenAndServe(":9000",nil)
- }
上面的太简单,就是一个http的服务,启动打开浏览器就可以输出hello world了,这是http,每次一个请求一个返回,虽然http的1.1版本已经支持keep-alive了,但如果想从服务发送到客户端,还是不行的,那么就诞生了websocket了。
现在改进一下代码:
- package main
-
- import (
- "net/http"
- "github.com/gorilla/websocket"
- "fmt"
- )
- var upgrade = websocket.Upgrader{}
-
- func main() {
- http.HandleFunc("/",r *http.Request) {
- w.Write([]byte("hello world"))
- })
-
- http.HandleFunc("/v1/ws",r *http.Request) {
- conn,_ := upgrade.Upgrade(w,r,nil)
- go func(conn *websocket.Conn) {
- for{
- //mtype :TextMessage=1/BinaryMessage=-2/CloseMessage=8/PingMessage=9/PongMessage=10
- mtype,msg,_:=conn.ReadMessage()
- switch mtype {
- case 1:
- conn.WriteMessage(mtype,msg)
- case 8:
- fmt.Println("close")
- }
- }
- }(conn)
-
- })
- http.ListenAndServe(":9000",nil)
- }
这个里面如果请求的是v1/ws的话就进入websocket的,就是把用户的输入当做输出,返回到客户端。下面通过浏览器console测试一下
- var ws = new WebSocket("ws://127.0.0.1:9000/v1/ws")
- ws.addEventListener("message",function(e){console.log(e);});
- ws.send("123")
运行一下就可以看到效果。当然,如果你不想返回,只是在后端输出一下
- mtype,_:=conn.ReadMessage()
- fmt.Println(mtype,":",string(msg))
那么前端就收不到任何返回。
进一步,那么如何后端推送呢,
- http.HandleFunc("/v1/ws",func(w http.ResponseWriter,r *http.Request) {
- conn,_ := upgrade.Upgrade(w,nil)
- go func(conn *websocket.Conn) {
- ch :=time.Tick(5*time.Second)
- for range ch{
- fmt.Println("call")
- conn.WriteMessage(1,[]byte("abc"))
-
- }
- }(conn)
-
- })
这样只要前端绑定了这个message就可以定时收到后端的推送了。但是如果前端关闭ws.close()将不会收到推送了。
在结束这篇blog之前还要补充一点就是服务关闭,如果前端关闭,后端任然继续读取数据将会报错panic: repeated read on Failed websocket connection。因为无法读取到客户端的数据了。所以还要在第一个例子的地方加上一个异常处理
- mtype,err:=conn.ReadMessage()
- if err != nil{
- conn.Close()
- return
- }
第一篇入门就和大家分享到这来