Если клиент запрашивает субпротоколы, а сервер не соглашается с одним из этих субпротоколов, то клиент должен закрыть соединение. Клиент использует заголовок 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
},
}
Второй - согласовать протокол в коде приложения до того, какпозвоните, чтобы обновить. Вызовите websocket.Subprotocols , чтобы получить запрошенные протоколы, выберите один из протоколов и укажите этот протокол в аргументе заголовка для Upgrade.
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 возвращает сообщение, отличное от nil, в случае успеха.
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))
}