javascript - 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的误解在哪里?
解决方案
推荐阅读
- python - 如何在 Python 中实现 KS-Test
- python - 将变量传递给另一个函数python定义的参数
- java - 设置在鼠标按下时移动
- java - Java Date to Epoch,受 Java7 的 Api 21 (Android) 限制
- python - Python中多变量、多类型RNN的实现
- amazon-web-services - 未能成功验证 kops 集群状态
- javascript - 如果对象键存在于另一个数组中,则在重新选择选择器中使用键对象扩充对象
- javascript - ES6 回调函数
- vega - 是否可以控制 vega 图表中非同级标记的分层?
- discord.py - 我怎样才能让机器人改变它的存在(听、看、玩等)以他们的名字显示在不和谐上?