首頁 > 後端開發 > Golang > 主體

websocket:客戶端未使用 websocket 協定:「連線」標頭中找不到「升級」令牌

王林
發布: 2024-02-09 14:24:10
轉載
1220 人瀏覽過

websocket:客户端未使用 websocket 协议:“连接”标头中未找到“升级”令牌

在進行 WebSocket 連線時,有時會出現「用戶端未使用 WebSocket 協定:「連線」標頭中找不到「升級」令牌」的錯誤。這個錯誤通常是由於客戶端沒有正確地使用 WebSocket 協定所導致的。 WebSocket 是一種在客戶端和伺服器之間實現雙向通訊的協議,它使用了一種特殊的握手過程來建立連接。在握手過程中,客戶端需要正確地發送「升級」標頭來表示使用 WebSocket 協定。如果用戶端未正確傳送該標頭,伺服器就會傳回上述錯誤。 php小編百草將在本文中詳細介紹如何解決這個問題,讓您的 WebSocket 連線順利進行。

問題內容

我正在嘗試與用 go 和 javascript 前端編寫的伺服器建立 websocket 連接。我在一個目錄中有以下檔案:

main.go 索引.html

**這是我在 main.go 中的 go 程式碼:**

package main


import (
    "fmt"
    "log"
    "net/http"

    "github.com/gorilla/websocket"
)

var upgrader = websocket.upgrader{
    readbuffersize:  1024,
    writebuffersize: 1024,
}

func homepage(w http.responsewriter, r *http.request) {
    http.servefile(w, r, "./index.html")
    conn, err := upgrader.upgrade(w, r, nil)
    if err != nil {
        log.println("error in handler:", err)
        return
    }
    log.println("client connected.")

    for {
        messagetype, p, err := conn.readmessage()
        if err != nil {
            log.println("fehler in readmessage: ", err)
            return
        }

        log.println(string(p))

        //echo message to client
        if err := conn.writemessage(messagetype, p); err != nil {
            log.println(err)
            return
        }
    }
}

func setuproutes() {
    http.handlefunc("/ws", homepage)
}

func main() {
    fmt.println("server gestartet")
    setuproutes()
    log.fatal(http.listenandserve(":9100", nil))

}
登入後複製

這是index.html中的html和javascript:

#
<!doctype html>
<html lang="de">
<head>
    <meta charset="utf-8">
    <title>some unimportant html </title>
</head>
<body>
    
    <script>


        let socket = new websocket("ws://localhost:9100/ws");
        console.log("websocket started.");

        socket.onopen = () => {
            console.log("client started.");
        }

        socket.onclose = (event) => {
            console.log("socket closed: ", event);
        }

        socket.onerror = (error) => {
            console.log("socket error: ", error);
        }

        socket.onmessage = (msg) => {
            console.log(msg);
        }
    </script>
</body>
</html>
登入後複製

但是,當我使用 go run main.go 運行該東西時 我收到以下錯誤:

#
2022/11/20 16:38:33 http: superfluous response.writeheader call from github.com/gorilla/websocket.(*upgrader).returnerror (server.go:83)
2022/11/20 16:38:33 error in handler: websocket: the client is not using the websocket protocol: 'upgrade' token not found in 'connection' header
2022/11/20 16:38:33 error in handler: write tcp [::1]:9100->[::1]:63712: wsasend: eine bestehende verbindung wurde softwaregesteuert durch den hostcomputer abgebrochen.
2022/11/20 16:39:06 error in handler: write tcp [::1]:9100->[::1]:63733: wsasend: eine bestehende verbindung wurde softwaregesteuert durch den hostcomputer abgebrochen.
exit status 0xc000013a
登入後複製

德文的意思是「現有的連線是由主機軟體控制終止的」

我遺漏了一些東西,而且我的理解不夠深入,無法找出問題所在。非常感謝任何幫助!

我想也許我的 js websocket 缺少升級,但在 chrome 中我可以看到請求 url ws://localhost:9100/ws 的以下請求標頭,上面寫著“upgrade:websocket”

Accept-Encoding: gzip, deflate, br
Accept-Language: de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7
Cache-Control: no-cache
Connection: Upgrade
Host: localhost:9100
Origin: http://localhost:9100
Pragma: no-cache
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Sec-WebSocket-Key: h3DWLuXsI9/GkTo+sIjyzw==
Sec-WebSocket-Version: 13
Upgrade: websocket
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36
登入後複製

解決方法

感謝 cerise limón 的有用評論,我得以修復它。問題是我需要一個用於索引檔案的端點,另一個用於 websocket 的端點。所以我將相關部分改為:

func websocketHandler(w http.ResponseWriter, r *http.Request) {
    conn, err := upgrader.Upgrade(w, r, nil) //conn is a websocket connection (aus http wird websocket protokoll)
    if err != nil {
        log.Println("Error in handler:", err)
        return
    }
    log.Println("Client connected.")

    
    for {
        messageType, p, err := conn.ReadMessage()
        if err != nil {
            log.Println("Fehler in ReadMessage: ", err)
            return
        }

        log.Println(string(p))

        //echo message to client
        if err := conn.WriteMessage(messageType, p); err != nil {
            log.Println(err)
            return
        }
    }
}

func homePage(w http.ResponseWriter, r *http.Request) {
    http.ServeFile(w, r, "./index.html")
}

func setupRoutes() {
    http.HandleFunc("/", homePage)
    http.HandleFunc("/ws", websocketHandler)

}
登入後複製

以上是websocket:客戶端未使用 websocket 協定:「連線」標頭中找不到「升級」令牌的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:stackoverflow.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!