首页 > 解决方案 > Go Nginx Websocket“在收到握手响应之前连接已关闭”

问题描述

我的本地主机上运行了一个 Go Web 服务器。我使用 Nginx 作为反向代理,将协议更改为ws在我的服务器上访问某个路由时。

我的浏览器中不断收到此错误消息 -(index):13 WebSocket connection to 'ws://127.0.0.1:8080/ws' failed: Connection closed before receiving a handshake response

此外,Go 服务器不断打印此错误 -read tcp [::1]:8080->[::1]:59967: read: connection reset by peer

我在 nginx.conf 文件中尝试了多种组合。我似乎无法让他们中的任何一个工作。

去:

package main

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

    "github.com/gorilla/websocket"
)

func reader(conn *websocket.Conn) {
    for {
        messageType, p, err := conn.ReadMessage()
        if err != nil {
            log.Println(err)
            return
        }
        fmt.Println(string(p))

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

    }
}

func homePage(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Home Page")
}

func wsEndpoint(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello World")
    ws, err := websocket.Upgrade(w, r, nil, 1024, 1024)
    if err != nil {
        http.Error(w, "Could not open websocket connection", http.StatusBadRequest)
        log.Println(err)
        return
    }

    log.Println("Client Connected")

    err = ws.WriteMessage(1, []byte("Hi Client!"))
    if err != nil {
        log.Println("Error")
        log.Println(err)
        return
    }

    reader(ws)
}

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

func main() {
    fmt.Println("Hello World")
    setupRoutes()
    log.Fatal(http.ListenAndServe(":8080", nil))
}

索引.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Go WebSocket Tutorial</title>
  </head>
  <body>
    <h2>Hello World</h2>

    <script>
      let socket = new WebSocket("ws://127.0.0.1:8080/ws");
      console.log("Attempting Connection...");

      socket.onopen = () => {
        console.log("Successfully Connected");
        socket.send("Hi From the Client!");
      };

      socket.onmessage = msg => {
        console.log(msg);
      };

      socket.onclose = event => {
        console.log("Socket Closed Connection: ", event);
        socket.send("Client Closed!");
      };

      socket.onerror = error => {
        console.log("Socket Error: ", error);
      };
    </script>
  </body>
</html>

nginx.conf

  {
    server {
        listen       8080;
        server_name  localhost;

        location /ws {
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header Host $http_host;
          proxy_set_header X-NginX-Proxy true;

          proxy_pass http://localhost:8080/ws;
          proxy_redirect off;

          proxy_http_version 1.1;
          proxy_set_header Upgrade $http_upgrade;
          proxy_set_header Connection "Upgrade";
        }

        location / {
            # root   html;
            # index  index.html index.htm;
            proxy_pass http://localhost:8080;
        }
    }

我期待 websocket 连接无限期地保持打开状态。我不知道究竟是什么关闭它以及为什么。

任何关于我做错了什么的建议都非常感谢。

标签: gonginxwebsocket

解决方案


推荐阅读