首页 > 解决方案 > NGINX 部署的 socket.io 服务器的 Socket.io 客户端问题

问题描述

嗨,大家好

我使用带有 TypeScript 和 MongoDB 的快速后端创建了一个简单的聊天应用程序。为了实时发送数据,我一直在使用socket.io在我的本地主机测试环境中一切正常,但是当我使用 NGINX 部署我的网页时它却没有。

我自己的猜测是我访问前端套接字的方式有问题。

下面是我的 NGINX 设置文件(启用站点的默认值),我在其中为socket.io设置了一个特定位置,为我的后端 REST 端点设置了一个位置。

出于隐私原因,我更改了我的服务器名称 :)

我的 NGINX 配置文件:site-enabled-default

server {

        server_name example.com www.example.com;

        location / {
                root /var/www/example/;
        }

        location /socket.io/ {
                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_set_header Host $http_host;
                proxy_pass http://localhost:5555/;
                proxy_redirect off;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
        }
        location /backend/ {
                proxy_http_version 1.1;
                proxy_cache_bypass $http_upgrade;

                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection 'upgrade';
                proxy_set_header Host $host;
                proxy_pass http://localhost:5555/;
        }

    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/segatos.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/segatos.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

server {
    if ($host = example.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


        listen 80 default_server;
        listen [::]:80 default_server;

        server_name example.com;
    return 404; # managed by Certbot

}

这是我的 app.ts 中socket.io部分的服务器端设置代码,在这个文件中,我的整个快速服务器都设置了各种选项和路由。

const app = express();

/*
    More setup code 
    Ratelimit 
    Cors setup
    BodyParser 
*/

const http = require("http");
export const server = http.createServer(app);
const io = require("socket.io")(server, { cors: { origin: "*" } });

io.sockets.on("connection", (socket) => {
  console.log("a user connected");
});
app.set("io", io);

/*
    More express setup with endpoints etc 
/*

在 www.ts 文件中,我创建了一个数据库连接并告诉服务器监听我选择的端口。这是在 .env 文件中定义的。

import { server } from "../app";

const PORT = process.env.PORT || 3333;

/*
    Some DB connections here 
    Starting the server afterwards 
*/

server.listen(PORT, () =>
    debug(`Server started, listening on PORT: ${PORT}`)
  );

前端明智,如前所述,我使用 react 并创建了一个使用 useContext 的 SocketProvider 组件。

然后我将子组件包装在 SocketProvider 中。

import React, { useContext, useEffect, useState } from "react";
import io from "socket.io-client";
import { SERVER_URL_SOCKET } from "../util/Settings";
//SERVER_URL_SOCKET == https://example.com/socket.io/";

const SocketContext = React.createContext();

export function useSocket() {
  return useContext(SocketContext);
}

export function SocketProvider({ id, children }) {
  const [socket, setSocket] = useState();

  useEffect(() => {
    const newSocket = io(SERVER_URL_SOCKET, { query: { id } });

    setSocket(newSocket);

    return () => newSocket.close();
  }, [id]);

  return (
    <SocketContext.Provider value={socket}>{children}</SocketContext.Provider>
  );
}

就像现在一样,我尝试将 SocketProvider 中的服务器 url 更改为 localhost:PORT 并为 nginx 设置文件尝试了许多不同的设置配置。

我还尝试打开已部署网页上的所有端口(暂时禁用防火墙)。

在浏览器的网络选项卡中,我可以看到socket.io不断创建此请求。

网络选项卡的图片

所以总结一下我的问题是后端 REST 端点正在工作,但我无法连接到我的套接字以使用在我的本地测试环境中工作的套接字功能。

例如,在本地测试环境中,套接字打印“用户已连接”。

我对如何在已部署的网页上设置和使用socket.io的误解在哪里?

标签: javascriptnode.jsreactjsnginxsocket.io

解决方案


推荐阅读