Socket.io - 连接失败:在接收到握手响应之前关闭了连接

22

NodeJS的Socket.io似乎不能作为WebSocket服务器运行

由于某种原因,socket.io总是退回到长轮询,如果我强制使用WebSocket传输层,则会出现以下错误:

失败:在接收握手响应之前关闭连接

正确的端口已经打开。我正在使用来自socket.io的聊天示例。 我在http://jmi.io:3000上设置了服务器。正如您看到的,它可以通过美丽的长轮询通道很好地工作,但现在尝试从WebSocket客户端进行WebSocket连接,结果是...

WebSocket连接到'ws://jmi:3000/'失败:在接收握手响应之前关闭连接

我只有一个单线程的节点,并且与聊天示例仓库中的package.json完全相同。

{
  "name": "socket-chat-example",
  "version": "0.0.1",
  "description": "my first socket.io app",
  "dependencies": {
    "express": "4.3.1",
    "socket.io": "1.2.0"
  }
}

感谢您的帮助


你解决了这个问题吗? - vlio20
5个回答

30

我遇到了完全相同的问题,因为我定义了两次“io”。请仔细检查您在代码中定义io的位置,并确保您没有两次定义变量io。

我之前做错的示例:

var server = require('http').createServer(app);
var io = require('socket.io')(server);

var io = require('socket.io').listen(server.listen(config.port, config.ip, function () {
    console.log('Express server listening on %d, in %s mode', config.port,     
    app.get('env'));
}));

解决问题的示例:

var server = require('http').createServer(app);
var io = require('socket.io')(server);

server.listen(config.port, config.ip, function () {
    console.log('Express server listening on %d, in %s mode', config.port, 
    app.get('env'));
});

3
在我的情况下,我在两个不同的位置调用了 require('socket.io')(server)。 - OpenUserX03
2
该死!这也发生在我身上了!感谢您的答案。 - Richard Clayton
1
在我的情况下,似乎是两次调用 listen 函数破坏了我的连接。 - Colin Newell
1
我这边也遇到了同样的问题。我从某个地方找到了一些代码,看起来像这样:var socketIo = require('socket.io'); var sio = socketIo.listen(httpServer); sio.serveClient(true); sio.attach(httpServer);attach和listen可能在做相同的事情,导致程序崩溃。 - LukeP
你太棒了!我也曾经调用过两次 require('socket.io')(server)! - AlexanderGriffin
我希望这是我的问题 :( - Jamie Hutber

7
略微与@Lucas Klaassen的回答有关:我有以下内容:
let express = require('express');
let app = express();
let http = require('http').Server(app);
let io = require('socket.io')(http);
// this is the culprit:
app.listen(port);

修改最后一行是解决问题的关键:

http.listen(port);

为什么?这对我来说毫无意义。 - Muhammad Umer
2
已弄清楚应用程序变量实际上不是服务器,而只是可以传递给服务器的普通JS对象。但是它有一个方便的函数叫做“listen”,尽管有些误导人,因为你可能会认为它与HTTP服务器的“listen”函数相同,即http.listen().. 但好的一面是http.listen()返回一个服务器,因此你可以server = app.listen(....).. io = require('socket.io')(server) - Muhammad Umer
1
@MuhammadUmer 谢谢!你的评论帮了我很多。 - nuovecode

4
在我的情况下,问题在于我通过 browser-sync 代理服务器。
browserSync({
    //server: {
    //  // src is included for use with sass source maps
    //  baseDir: ['public', 'src']
    //},
    proxy: "localhost:4045",
    port: 4046

所以这将失败,但在生产中它可以正常工作。

太棒了。这也是我的问题。 - Jase Pellerin
1
为了解决BrowserSync的问题,您可以设置ws:true。例如:proxy: {target: localhost, ws: true}。在我的项目中它运行良好。 - Zagonine
ws: true 对我来说并没有解决问题。我仍然收到相同的错误信息。还有其他方法吗? - Ripal Tamboli

0

这是我们一个工作项目中的完整示例:

const websocket = require('ws');
const http = require('http');
const express = require('express');
const app = express();
const server = http.createServer(app);
wss = new websocket.Server({ server });
app.on('upgrade', wss.handleUpgrade);

wss.on('connection', ws => {
  console.log('web socket connection is alive');
}

server.listen(8080, () => {
    console.log('server started on PORT 8080');
});

翻译自Medium


0

这对我有用!

restUrl = 'http://x.x.x.x:5555;

socket = io(this.restUrl, {
        transports: ["websocket"],
        upgrade: true,
        upgradeTimeout: 6000000,
        pingTimeout: 15000000000,
        pingInterval: 1500000000,
        maxHttpBufferSize: 10000000,
      });

connect() {
        if (this.socket.connected == false) {
            var temp = this;
            this.socket.connect();
            this.socket.on('event', function (data) {
                temp.socketData.next(data);
            });
        }
    }

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