使用nginx代理的Websocket

3

我在使用nginx代理时,websocket连接遇到了问题。如果我将端口添加到use effect中,则可以正确连接。

以下是react的代码:

useEffect(() => {
    console.log('web socket')
    const socket = new WebSocket(`ws://${window.location.hostname}/websocket`);
    socket.onopen = () => socket.send('Connected to React')
    setSocketIo(socket)
}, [])

这是nginx配置片段。
location /websocket/ {
        proxy_pass http://localhost:8000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header Host $host;
    }

这是我在控制台中收到的错误信息。 WebSocket 连接到 'ws://localhost/websocket' 失败:

从 nginx 日志中看到的错误信息: 2022/04/13 13:23:42 [error] 16848#8212: *1499 connect() failed (10061: No connection could be made because the target machine actively refused it) while connecting to upstream, client: 127.0.0.1, server: localhost, request: "GET /socket.io/?EIO=4&transport=polling&t=O0ac97J HTTP/1.1", upstream: "http://[::1]:3000/socket.io/?EIO=4&transport=polling&t=O0ac97J", host: "localhost", referrer: "http://localhost/guac"

它会自动将 socket.io 添加到主机名的末尾吗?

你遇到了什么“无法正确连接WebSocket”的问题?你的浏览器控制台或Nginx服务器日志中有任何错误吗? - user973254
这是我在控制台中收到的错误信息。 WebSocket连接到'ws://localhost/websocket'失败:来自nginx日志的错误信息 2022/04/13 13:23:42 [error] 16848#8212: *1499 connect() failed (10061: No connection could be made because the target machine actively refused it) while connecting to upstream, client: 127.0.0.1, server: localhost, request: "GET /socket.io/?EIO=4&transport=polling&t=O0ac97J HTTP/1.1", upstream: "http://[::1]:3000/socket.io/?EIO=4&transport=polling&t=O0ac97J", host: "localhost", referrer: "http://localhost/guac" - Vinh Ta
根据nginx日志,您的fastapi WebSocket服务器拒绝来自nginx的连接。 - user973254
在你的 error.log 中看到 GET /socket.io/...,检查你的代码(请求方) - user973254
我的代码中没有使用/socket.io/。它会自动将其放在URL的末尾。这是WebSocket应该做的吗? - Vinh Ta
显示剩余7条评论
1个回答

1

我使用django-channels,这是我的工作nginx设置,希望对你有所帮助。顺便说一句,我仍然没有在生产中使用它,但在开发中可以正常工作。您可以配置为使用WSS的WebSocket。

upstream channels-backend {
    server localhost:8000;
    # here you connect your channel ip:port
}


server {
    server_name  example.com www.example.com;
        location /static/ {
        }
        location /media {
        }
        location / {
            include proxy_params;
            proxy_pass http://unix:/yourGunicorn.sock;
            # This is for Nginx connection to gunicorn
        }

        location /ws/ {
            try_files $uri @proxy_for_websocket;
            # websocket connection comes with ws
        }
        location @proxy_for_websocket {
            proxy_pass http://channels-backend;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_redirect off;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Host $server_name;
        }
        listen [::]:443 ssl ipv6only=on;
        listen 443 ssl;
        # Your certificate detail here
}

从JavaScript中,您正在尝试连接

 const socket = new WebSocket(`ws://${window.location.hostname}/websocket`);

ws协议,而且在你的nginx中写入了以下内容:

location /websocket/ {
     ---
     ---
    }

这完全是错误的。应该是 -
location /ws/ {
     ---
     ---
    }

希望这能有所帮助 :)

谢谢!这很有帮助。实际上,我发现问题是由于不支持的uvicorn版本引起的。它需要使用uvicorn[standard]而不是uvicorn - Vinh Ta
我使用Daphne作为我的Django :) - Ranu Vijay

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接