WebSocket:客户端未使用websocket协议:在“Connection”标头中找不到“upgrade”标记

qyswt5oh  于 2022-11-24  发布在  其他
关注(0)|答案(1)|浏览(937)

我正在尝试建立一个WebSocket连接,连接服务器是用Go语言编写的,并使用了JavaScript前端。我在一个目录中有以下文件:
主页

这是我在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的以下请求标头,上面写着“升级: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
blmhpbnm

blmhpbnm1#

多亏了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)

}

相关问题