websocket: the client is not using the websocket protocol: 'upgrade' token not found in 'Connection' header

huangapple go评论125阅读模式
英文:

websocket: the client is not using the websocket protocol: 'upgrade' token not found in 'Connection' header

问题

我正在尝试在使用Go编写的服务器和JavaScript前端之间建立WebSocket连接。我在一个目录中有以下文件:

main.go
index.html

以下是我在main.go中的Go代码:

  1. package main
  2. import (
  3. "fmt"
  4. "log"
  5. "net/http"
  6. "github.com/gorilla/websocket"
  7. )
  8. var upgrader = websocket.Upgrader{
  9. ReadBufferSize: 1024,
  10. WriteBufferSize: 1024,
  11. }
  12. func homePage(w http.ResponseWriter, r *http.Request) {
  13. http.ServeFile(w, r, "./index.html")
  14. conn, err := upgrader.Upgrade(w, r, nil)
  15. if err != nil {
  16. log.Println("Error in handler:", err)
  17. return
  18. }
  19. log.Println("Client connected.")
  20. for {
  21. messageType, p, err := conn.ReadMessage()
  22. if err != nil {
  23. log.Println("Fehler in ReadMessage:", err)
  24. return
  25. }
  26. log.Println(string(p))
  27. //echo message to client
  28. if err := conn.WriteMessage(messageType, p); err != nil {
  29. log.Println(err)
  30. return
  31. }
  32. }
  33. }
  34. func setupRoutes() {
  35. http.HandleFunc("/ws", homePage)
  36. }
  37. func main() {
  38. fmt.Println("Server gestartet")
  39. setupRoutes()
  40. log.Fatal(http.ListenAndServe(":9100", nil))
  41. }

以下是index.html中的HTML和JavaScript代码:

  1. <!DOCTYPE html>
  2. <html lang="de">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Some unimportant html </title>
  6. </head>
  7. <body>
  8. <script>
  9. let socket = new WebSocket("ws://localhost:9100/ws");
  10. console.log("Websocket started.");
  11. socket.onOpen = () => {
  12. console.log("Client started.");
  13. }
  14. socket.onclose = (event) => {
  15. console.log("Socket closed: ", event);
  16. }
  17. socket.onError = (error) => {
  18. console.log("Socket Error: ", error);
  19. }
  20. socket.onMessage = (msg) => {
  21. console.log(msg);
  22. }
  23. </script>
  24. </body>
  25. </html>

然而,当我使用go run main.go运行时,我得到以下错误:

  1. 2022/11/20 16:38:33 http: superfluous response.WriteHeader call from github.com/gorilla/websocket.(*Upgrader).returnError (server.go:83)
  2. 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
  3. 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.
  4. 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.
  5. exit status 0xc000013a

德语部分的意思是“现有连接被主机计算机软件控制终止”。

我可能遗漏了一些东西,我的理解不够深入,无法确定问题出在哪里。非常感谢任何帮助!

我想也许我的JS WebSocket缺少升级,但是在Chrome中,我可以看到请求URL ws://localhost:9100/ws 的请求头,其中包含“Upgrade: websocket”:

  1. Accept-Encoding: gzip, deflate, br
  2. Accept-Language: de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7
  3. Cache-Control: no-cache
  4. Connection: Upgrade
  5. Host: localhost:9100
  6. Origin: http://localhost:9100
  7. Pragma: no-cache
  8. Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
  9. Sec-WebSocket-Key: h3DWLuXsI9/GkTo+sIjyzw==
  10. Sec-WebSocket-Version: 13
  11. Upgrade: websocket
  12. 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
英文:

I am trying to set up a websocket connection with the server written in Go and a JavaScript frontend. I have the following files in one directory:

main.go
index.html

**This is my Go code in main.go: **

  1. package main
  2. import (
  3. &quot;fmt&quot;
  4. &quot;log&quot;
  5. &quot;net/http&quot;
  6. &quot;github.com/gorilla/websocket&quot;
  7. )
  8. var upgrader = websocket.Upgrader{
  9. ReadBufferSize: 1024,
  10. WriteBufferSize: 1024,
  11. }
  12. func homePage(w http.ResponseWriter, r *http.Request) {
  13. http.ServeFile(w, r, &quot;./index.html&quot;)
  14. conn, err := upgrader.Upgrade(w, r, nil)
  15. if err != nil {
  16. log.Println(&quot;Error in handler:&quot;, err)
  17. return
  18. }
  19. log.Println(&quot;Client connected.&quot;)
  20. for {
  21. messageType, p, err := conn.ReadMessage()
  22. if err != nil {
  23. log.Println(&quot;Fehler in ReadMessage: &quot;, err)
  24. return
  25. }
  26. log.Println(string(p))
  27. //echo message to client
  28. if err := conn.WriteMessage(messageType, p); err != nil {
  29. log.Println(err)
  30. return
  31. }
  32. }
  33. }
  34. func setupRoutes() {
  35. http.HandleFunc(&quot;/ws&quot;, homePage)
  36. }
  37. func main() {
  38. fmt.Println(&quot;Server gestartet&quot;)
  39. setupRoutes()
  40. log.Fatal(http.ListenAndServe(&quot;:9100&quot;, nil))
  41. }

And this is the HTML and JavaScript in index.html:

  1. &lt;!DOCTYPE html&gt;
  2. &lt;html lang=&quot;de&quot;&gt;
  3. &lt;head&gt;
  4. &lt;meta charset=&quot;UTF-8&quot;&gt;
  5. &lt;title&gt;Some unimportant html &lt;/title&gt;
  6. &lt;/head&gt;
  7. &lt;body&gt;
  8. &lt;script&gt;
  9. let socket = new WebSocket(&quot;ws://localhost:9100/ws&quot;);
  10. console.log(&quot;Websocket started.&quot;);
  11. socket.onOpen = () =&gt; {
  12. console.log(&quot;Client started.&quot;);
  13. }
  14. socket.onclose = (event) =&gt; {
  15. console.log(&quot;Socket closed: &quot;, event);
  16. }
  17. socket.onError = (error) =&gt; {
  18. console.log(&quot;Socket Error: &quot;, error);
  19. }
  20. socket.onMessage = (msg) =&gt; {
  21. console.log(msg);
  22. }
  23. &lt;/script&gt;
  24. &lt;/body&gt;
  25. &lt;/html&gt;

However, when I run the thing with go run main.go I get the following error:

  1. 2022/11/20 16:38:33 http: superfluous response.WriteHeader call from github.com/gorilla/websocket.(*Upgrader).returnError (server.go:83)
  2. 2022/11/20 16:38:33 Error in handler: websocket: the client is not using the websocket protocol: &#39;upgrade&#39; token not found in &#39;Connection&#39; header
  3. 2022/11/20 16:38:33 Error in handler: write tcp [::1]:9100-&gt;[::1]:63712: wsasend: Eine bestehende Verbindung wurde softwaregesteuert durch den Hostcomputer abgebrochen.
  4. 2022/11/20 16:39:06 Error in handler: write tcp [::1]:9100-&gt;[::1]:63733: wsasend: Eine bestehende Verbindung wurde softwaregesteuert durch den Hostcomputer abgebrochen.
  5. exit status 0xc000013a

The German lines mean "the existing connection was software controlled terminated by the host computer"

I am missing something and my understanding doesn't run deep enough to pinpoint what's wrong. Any help is much appreciated!

I thought maybe my JS Websocket is missing an upgrade, but in Chrome I can see the following request header for Request URL ws://localhost:9100/ws that says "Upgrade:websocket"

  1. Accept-Encoding: gzip, deflate, br
  2. Accept-Language: de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7
  3. Cache-Control: no-cache
  4. Connection: Upgrade
  5. Host: localhost:9100
  6. Origin: http://localhost:9100
  7. Pragma: no-cache
  8. Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
  9. Sec-WebSocket-Key: h3DWLuXsI9/GkTo+sIjyzw==
  10. Sec-WebSocket-Version: 13
  11. Upgrade: websocket
  12. 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

答案1

得分: 1

感谢Cerise Limón的有用评论,我成功修复了它。问题是我需要一个用于索引文件的端点,另一个用于websocket。所以我将相关部分更改为以下内容:

  1. func websocketHandler(w http.ResponseWriter, r *http.Request) {
  2. conn, err := upgrader.Upgrade(w, r, nil) //conn是一个websocket连接(从http转换为websocket协议)
  3. if err != nil {
  4. log.Println("处理程序中的错误:", err)
  5. return
  6. }
  7. log.Println("客户端已连接。")
  8. for {
  9. messageType, p, err := conn.ReadMessage()
  10. if err != nil {
  11. log.Println("ReadMessage中的错误:", err)
  12. return
  13. }
  14. log.Println(string(p))
  15. //将消息回显给客户端
  16. if err := conn.WriteMessage(messageType, p); err != nil {
  17. log.Println(err)
  18. return
  19. }
  20. }
  21. }
  22. func homePage(w http.ResponseWriter, r *http.Request) {
  23. http.ServeFile(w, r, "./index.html")
  24. }
  25. func setupRoutes() {
  26. http.HandleFunc("/", homePage)
  27. http.HandleFunc("/ws", websocketHandler)
  28. }
英文:

Thanks to the helpful comment by Cerise Limón I was able to fix it. The problem was that I needed one endpoint for the index file and another one for the websocket. So I changed the relevant parts to this:

  1. func websocketHandler(w http.ResponseWriter, r *http.Request) {
  2. conn, err := upgrader.Upgrade(w, r, nil) //conn is a websocket connection (aus http wird websocket protokoll)
  3. if err != nil {
  4. log.Println(&quot;Error in handler:&quot;, err)
  5. return
  6. }
  7. log.Println(&quot;Client connected.&quot;)
  8. for {
  9. messageType, p, err := conn.ReadMessage()
  10. if err != nil {
  11. log.Println(&quot;Fehler in ReadMessage: &quot;, err)
  12. return
  13. }
  14. log.Println(string(p))
  15. //echo message to client
  16. if err := conn.WriteMessage(messageType, p); err != nil {
  17. log.Println(err)
  18. return
  19. }
  20. }
  21. }
  22. func homePage(w http.ResponseWriter, r *http.Request) {
  23. http.ServeFile(w, r, &quot;./index.html&quot;)
  24. }
  25. func setupRoutes() {
  26. http.HandleFunc(&quot;/&quot;, homePage)
  27. http.HandleFunc(&quot;/ws&quot;, websocketHandler)
  28. }

huangapple
  • 本文由 发表于 2022年11月21日 00:16:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/74509802.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定