简介
WebSocket是一种在单个TCP连接上进行全双工通信的协议。WebSocket让客户端和服务端之间的数据交换变得非常简单,且允许服务器主动向客户端推送数据,并且之后客户端和服务端所有的通信都依靠这个专用协议进行。
在websocket出现之前,一些网站为了实现消息的推送,采用最多的技术是Ajax轮询,每隔一段时间,由浏览器向服务器发出HTTP请求,然后由服务器返回最新的数据给浏览器。在这种模式下,浏览器需要不断地向服务器发出http请求,而http请求可能包含较长的头部,其中真正有效的数据可能只占一小部分,显然浪费带宽,影响传输效率。
而客户端和服务端之间的websocket连接一旦建立,就可以一直保持连接状态,不需要重复发起连接请求,能更好地节省网络带宽资源,实时性更高。
需要安装第三方包:
go get golang.org/x/net/websocket
示例代码:服务端server.go
package main import ( "fmt" "golang.org/x/net/websocket" "html/template" "net/http" ) func main() { fmt.Println("websocket at 127.0.0.1:8000/echo") http.Handle("/echo",websocket.Handler(Echo)) http.HandleFunc("/",handleIndex) if err := http.ListenAndServe("127.0.0.1:8000",nil); err != nil { fmt.Println(err) } } // Echo为处理程序 func Echo(w *websocket.Conn) { var err error for { var recMsg string if err = websocket.Message.Receive(w, &recMsg); err != nil { fmt.Println(err) break } fmt.Println("客户端: ",recMsg) msg := "" if recMsg == "猜猜年龄" { msg = "server: 17岁" } else if recMsg == "你好" { msg = "server: 你好,请问有什么可以帮你?" } else { msg = "server: " + recMsg } fmt.Println(msg) // 发消息给客户端 if err = websocket.Message.Send(w, msg); err != nil { fmt.Println(err) break } } } // 返回静态html func handleIndex(writer http.ResponseWriter, request *http.Request) { t,_ := template.ParseFiles("index.html") t.Execute(writer,nil) }
客户端:index.html
服务端运行后,浏览器访问http://127.0.0.1:8000
,并打开开发者模式的控制台。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Html5 Websocket test</title> </head> <body> <script type="text/javascript"> var sock = null; var wsuri = "ws://127.0.0.1:8000/echo"; window.onload = function() { sock = new WebSocket(wsuri); // 建立连接时触发 sock.onopen = function() { console.log("connected to " + wsuri); } // 关闭连接时触发 sock.onclose = function(e) { console.log("connection clsoed (" + e.code + ")"); } // 收到消息时触发 sock.onmessage = function (e) { console.log("收到消息: " + e.data); } // 发生错误时触发 sock.onerror = function (e) { console.log("Error: " + wsuri); } }; // 发送消息 function send() { var msg = document.getElementById('message').value; if (sock) { sock.send(msg); } }; </script> <h1>Go WebSocket</h1> <form> <p> 消息: <input id="message" type="text" value="猜猜年龄"> </p> </form> <button onclick="send();">发送消息</button> </body> </html>
参考文档
- 百度百科 - websocket
- 汪明 - 《GO并发编程实战》清华大学出版社
- https://pkg.go.dev/golang.org/x/net/websocket