大家好
将我的 NodedJs 应用程序推送到我的 ubuntu 服务器(使用 https 在 nginx 中提供站点)后,我遇到了问题。在我使用 localhost 的本地环境中,连接已成功建立,但是在推送到服务器后,我在客户端 JavaScript 控制台内的第二个应用程序(管理员)admin.domainname.com 中收到以下响应:
manager.js:108 WebSocket connection to 'wss://domainname.com/socket.io/?EIO=4&transport=websocket' failed
这是我在domainname.com上运行的第一个应用程序中建立套接字并发送消息的部分:
/*rest of app.js file with express.js*/
const PORT = 3000;
const server = app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`)
})
const socket = socketIo(server);
socket.on('connection', (socket) => {
console.log("connected")
socket.emit("testmessage", "Hello World")
socket.on('disconnect', () => {});
});
在我的客户端 JavaScript 内的第二个应用程序 (admin.domainname.com) 中,我想接收如下消息:
const socketdomainconstruct = () => {
if (location.port) {
return "http://localhost:3000"
} else {
return "https://domainname.com"
}
}
const socket = io(socketdomainconstruct(), { transports: ['websocket', 'polling', 'flashsocket']
socket.on("connect", () => {
console.log("connected");
socket.on("testmessage", (message) => {
console.log(message);
});
});
为了解释,当我在上面的 socket.io 实例中使用 http://localhost:3000 时,我可以成功连接并且一切都按预期工作,因此整体结构没有问题。只有当我切换到 https 时,我才会收到错误,我似乎不明白,因为没有任何改变。
潜在问题可能在于:
app.use((req, res, next) => {
res.removeHeader('Server');
res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0');
res.setHeader('Pragma', 'no-cache');
res.setHeader('Expires', '0');
res.setHeader('Last-Modified', new Date().toUTCString());
res.setHeader('Content-Security-Policy', "default-src 'self'; script-src 'self' 'unsafe-inline' cdn.socket.io code.jquery.com cdn.jsdelivr.net; style-src 'self' 'unsafe-inline'; img-src 'self' bing.com; connect-src 'self' *");
res.setHeader('Permission-Policy', 'accelerometer=(), camera=(), microphone=(), geolocation=(), gyroscope=()');
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('X-Content-Type-Options', 'nosniff');
res.setHeader('X-Frame-Options', 'deny');
res.setHeader('X-XSS-Protection', '1; mode=block');
res.setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');
res.setHeader('Referrer-Policy', 'strict-origin-when-cross-origin');
next();
});
我希望有人可以帮助我澄清/隔离问题,甚至与我一起解决它,作为参考,我还将包含来自 Socket.io 的有用链接
预先感谢您提供的任何帮助和提示,这对我来说真的很有帮助!
干杯拉斐尔
问题已解决,首先将正确的 cors 选项添加到 SocketIO 服务器对象:
socketIo(服务器, {cors: {origin: ["https://admin.domainname.com", "http://localhost:3000"]}}); // 数组风格的写法可以包含多个原点...
请参阅有关 SocketIO 的文档了解更多信息:
我还必须正确设置 Nginx 代理,如下所示:
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://admin-container:4000; #localhost in case of not running the app inside a Docker container
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade; #important part for Websocket connection to work
proxy_set_header Connection 'upgrade'; #important part for Websocket connection to work
proxy_cache_bypass $http_upgrade;
}
这也可以在 SocketIO 文档中看到,它不仅适用于 Nginx,还适用于 Apache 和 Caddy2!
总的来说,这个问题可以通过正确阅读文档来避免,它们非常好,感谢大家的帮助,祝你有美好的一天,希望问题的解决可以帮助其他有类似问题的人
我的设置是
干杯拉斐尔