基于HTML5,提供一种浏览器与服务器进行全双工通讯的网络技术,应用层协议,基于TCP传输协议,并复用HTTP的握手通道(比传统的HTTP请求/响应模型更高效,因为它不需要建立和拆除连接,从而减少网络延迟)
全双工通信
持久连接
低延迟
Go语言的WebSocket库
gorilla/websocket 支持多路复用,自定义头部和心跳功能
golang.org/x/net/websocket 标准库,不支持多路复用,自定义头部和心跳
websocker服务器
package main import ( "fmt" "github.com/gorilla/websocket" "log" "net/http" ) var upgrader = websocket.Upgrader{CheckOrigin: func(r *http.Request) bool { return true }} func main() { fmt.Println("start my websocket") http.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) { conn, err := upgrader.Upgrade(w, r, nil) if err != nil { log.Fatal(err) } defer conn.Close() for { _, message, err := conn.ReadMessage() if err != nil { log.Fatal(err) break } fmt.Println("receive message: %s\n", message) err = conn.WriteMessage(websocket.TextMessage, []byte("pong")) if err != nil { log.Fatal(err) break } } }) err := http.ListenAndServe(":8080", nil) if err != nil { log.Fatal("listen happend error: ", err) } }
websocket 客户端
var upgrader = websocket.Upgrader{ CheckOrigin: func(r *http.Request) bool { return true }, }
func main() {
c, _, err := websocket.DefaultDialer.Dial("ws://localhost:8080/ws", nil)
if err != nil { log.Fatal(err) } defer c.Close()
for {
_, message, err := c.ReadMessage()
if err != nil {
log.Println(err)
break
}
fmt.Printf("Received: %s\n", message)
err = c.WriteMessage(websocket.TextMessage, []byte("Hello"))
if err != nil {
log.Println(err)
break
}
}