1 回答
TA贡献1862条经验 获得超6个赞
如果客户端请求子协议并且服务器不同意这些子协议之一,则客户端需要关闭连接。客户端使用 Sec-Websocket-Protocol 标头来请求一个或多个子协议。服务器使用 Sec-Websocket-Protocol 响应标头来同意协议。有关此主题的更多信息,请参阅RFC 。
通过同意客户端请求的协议之一来解决问题。有几种方法可以做到这一点。
第一种是使用内置的协议协商功能:
var upgrader = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
Subprotocols: []string{ "hey" }, // <-- add this line
CheckOrigin: func(r *http.Request) bool {
return true
},
}
第二种是在调用 Upgrade 之前在应用程序代码中协商协议。调用websocket.Subprotocols获取请求的协议,选择其中一种协议并在升级的标头参数中指定该协议。
h := http.Header{}
for _, sub := range websocket.Subprotocols(req) {
if sub == "hey" {
h.Set("Sec-Websocket-Protocol", "hey")
break
}
}
conn, err := upgrader.Upgrade(w, r, h)
除了这个问题之外,应用程序应该defer conn.Close()在成功升级后。
此外,还可以简化错误处理逻辑。应用程序应在从 ReadMessage 返回任何错误时退出读取循环。连接错误后写入消息是没有意义的。ReadMessage 方法在成功时返回非零消息。
for {
// Read message from browser
_, msg, err := conn.ReadMessage()
if err != nil {
fmt.Println(err.Error())
fmt.Println("disconnected")
return
}
WriteOutgoingMessage(conn, userID.Hex() + " " + string(msg))
}
- 1 回答
- 0 关注
- 156 浏览
添加回答
举报