我在socket.io
上运行的node.js
应用中使用express
。
本地版本(localhost
)上的所有单词都很好但是当我切换到我的生产服务器(使用自定义证书通过https
提供服务)时,我的浏览器控制台出现以下错误:
websocket.js:112 WebSocket connection to 'wss://infranodus.com/socket.io/?EIO=3&transport=websocket&sid=j_WBxkPY_RlpF9_ZAANP' failed: Error during WebSocket handshake: Unexpected response code: 400
我进行了一项研究(issue referenced here),事实证明这是因为我的应用/托管服务提供商屏蔽了wss
之类的连接,我的socket.io
会重新回到AJAX
提出请求(功能正常,但有时会有错误)。
所以我想问你是否可以对我的应用进行修改以摆脱这个错误?
目前只有FYI将http://infranodus.com的所有请求转发(通过静态.htaccess)到https://infranodus.com和我的app.js
文件(服务器激活的部分看起来像这样):
var http = require('http');
var app = express();
var server = http.Server(app);
var io = require('socket.io')(server);
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
以及我在前端文件中需要套接字的方式:
<script src="/socket.io/socket.io.js"></script>
然后
var socket = io();
也许问题是我使用http
而不是https
在我的node.js应用中激活服务器?但我不想改用它,因为我不知道我的证书存储在哪里,我不想太多地改变后端代码。
更新(21/10/2018):我们发现问题是with nginx server,并且由于某些托管服务提供商的限制,他们不允许用户编辑nginx服务器,websockets over secure protocol被阻止或获得400错误。在sockets.io中解决这个问题会很好,因为这是许多用户的问题。有什么想法吗?
重现问题:请打开您的Javascript控制台并转到https://infranodus.com/news/english
答案 0 :(得分:2)
检查您是否在快递上使用express-status-monitor
作为中间件,这会使WebSocket的第一次(请求)握手的http调用失败,如果不是其他因素(例如代理(nginx)或类似原因)>
查看here有关此错误的更多详细信息
答案 1 :(得分:2)
我用这个解决了:
var socket = io.connect("http://localhost:3000", {
forceNew: true,
transports: ["polling"],
});
答案 2 :(得分:0)
使用安全网址进行初始连接,即使用“https://”代替“http://”。如果选择了WebSocket传输,那么Socket.IO也应该自动使用“wss://”(SSL)进行WebSocket连接。
如果您在调用io()时未指定任何URL,因为它默认尝试连接到为该页面提供服务的主机,您必须提供URL或更改为https
var socket = io.connect('https://localhost', {secure: true}); //remote url
答案 3 :(得分:0)
请尝试以下两种方法
尝试此方法1:
我面临着同样的问题。调试30分钟后,我通过启用ALB(应用程序负载平衡器)粘性来解决了该问题。它对我有用。
尝试此方法2:
// Client side adding transport param:
var socket = io('http://localhost:3000', { transports: ['websocket'] });
您可以根据您的域将此值设置为“ http://localhost:3000”。
答案 4 :(得分:0)
我有同样的错误。
我决定访问infranodus.com/socket.io/?EIO=3&transport=websocket&sid=j_WBxkPY_RlpF9_ZAANP,它返回消息“会话ID未知”。
您使用了多个节点吗?在这种情况下,请访问网站https://socket.io/docs/using-multiple-nodes/。
如官方网站上所述,
如果您打算在不同的站点之间分配连接负载 流程或机器,您必须确保请求关联 具有特定会话ID的服务器连接到始发的进程 他们。
这是由于某些传输,例如XHR轮询或JSONP轮询 依赖于在生命周期内触发多个请求 “插座”。无法启用粘性平衡会导致 害怕:
Error during WebSocket handshake: Unexpected response code: 400
按照说明重新配置Nginx配置,然后尝试像这样修改Express
let port = parseInt(your_port) + parseInt(process.env.NODE_APP_INSTANCE);
server.listen(port, console.log("Server running "+port));
让我们知道它是否会有所改变:)
答案 5 :(得分:0)
我在后端更新包时遇到了这个问题,python socketio,但没有在前端更新。
但是当我到处更新软件包时,问题就解决了。 这是版本问题
在返回 400 错误时导航到链接后,我在浏览器中发现了此错误 “客户端正在使用不受支持的 Socket.IO 或 Engine.IO 协议版本”