Sec-Websocket-协议问题

我在使用 WebSockets 协议时遇到 Go 问题。如果我连接到我的 API,一切都会正常。如果我添加“协议”,例如“Hey”,它会开始循环多次,并以错误结束*github.com/gorilla/websocket.CloseError:“Code 1006,Text Unexpected EOF”。


Sec-Websocket-Protocol我绝对不明白为什么当我在连接中发送时它会这样。


有我的代码:


main.go


package main


import (

    "fmt"

    "github.com/golang/glog"

    "github.com/grpc-ecosystem/grpc-gateway/runtime"

    stacktracer "gitlab.com/eyes-eyes/internals-stacktracer"

    "gitlab.com/eyesbank/go-web-sockets-server/handlers"

    "net/http"

)


const webSocketsAddr = "0.0.0.0:8082"


// main is the starting point of the current micro service.

func main() {


    // Setting the service name

    stacktracer.SetServiceName("Hello 'X' (Web Sockets)")


    // Initializing the HTTP errors handling

    runtime.HTTPError = stacktracer.DefaultHTTPError


    if err := RunWebSocketsServer(); err != nil {

        glog.Fatal(err)

    }


}


//

// WebSocket

//


func RunWebSocketsServer() error {


    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {

        handlers.HandleUserSocket(w, r)

    })


    fmt.Println(webSocketsAddr)


    return http.ListenAndServe(webSocketsAddr, nil)

}


func RunWebSocketsTLSServer() error {


    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {

        handlers.HandleUserSocket(w, r)

    })


    fmt.Println(webSocketsAddr)


    return http.ListenAndServeTLS(webSocketsAddr, "server.crt", "server.key", nil)

}


人到中年有点甜
浏览 97回答 1
1回答

阿波罗的战车

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