Socket.io 无法连接,求助于“轮询”

Posted

技术标签:

【中文标题】Socket.io 无法连接,求助于“轮询”【英文标题】:Socket.io cannot connect, resorts to "polling" 【发布时间】:2015-03-15 21:51:24 【问题描述】:

我正在尝试创建一个 websocket 客户端-服务器应用程序,其中客户端和服务器将在两个不同的实例上运行。

设置

服务器/后端:在 localhost:9006 上运行,angular-fullstack generator 包括 socket.io 客户端/前端:在localhost:9007 上运行angular generator + socket.io-client + btford.socket-io(AngularJS socket.io 桥)

服务器

注意:不是完整的代码,但我认为相关的部分。

// ----- socketio.js -----

// When the user connects.. perform this
function onConnect(socket) 
    // When the client emits 'info', this listens and executes
    socket.on('info', function (data) 
        console.info('[%s] %s', socket.address, JSON.stringify(data, null, 2));
        socket.emit('pong', 'OK!');
    );
    // Insert sockets below
    require('../api/thing/thing.socket').register(socket);


socketio.set('origins', 'http://localhost:9007');

// ----- express.js -----

app.use(function (req, res, next) 
    res.setHeader('Access-Control-Allow-Origin', 'http://localhost:9007');
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
    res.setHeader('Access-Control-Allow-Credentials', true);
    next();
);

// ----- app.js -----

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

客户

// ----- client app.js

angular
.module('weldCommentsClientApp', [
    'ngAnimate', 'ngAria', 'ngCookies', 'ngMessages', 'ngResource', 'ngRoute', 'ngSanitize', 'ngTouch',
    'btford.socket-io'
])
.factory('mySocket', function (socketFactory) 
    var myiosocket = window.io.connect('http://localhost:9006');
    var mySocket = socketFactory(
        ioSocket: myIoSocket
    );
    mySocket.forward('pong');
    console.log('mySocket', mySocket);
    return mySocket;
)

// ----- client main.js

angular.module('weldCommentsClientApp').controller('MainCtrl', function ($scope, mySocket) 
    $scope.$on('socket:pong', function (ev, data) 
        console.log('socket:pong', ev, data);
    );
    mySocket.emit('info');
);

结果

服务器和客户端都没有控制台错误,但它不起作用,服务器记录了 100 条以下行:

GET /socket.io/?EIO=3&transport=polling&t=1421488528935-16027 200 2ms

...看起来客户端通过 HTTP 连接,但无法切换到 websockets。

有什么想法吗?

更新

这是整个客户端/服务器项目,README 中有说明:https://github.com/weld-io/socket.io-client-server-boilerplate

【问题讨论】:

socket.io 协议以协商要使用的连接类型的请求开始。你能告诉我们这方面的要求/要求吗? 你使用的是什么版本的socket.io? 一些防病毒软件往往会与 websockets 混淆。尝试禁用防病毒软件或通过 https 运行。 你试过取消限制了吗..socketio.set('origins', 'http://localhost:9007') 尝试将$scope.$on('socket:pong'改为$scope.$on('pong' 【参考方案1】:

server/app.js 中路径定义不正确

尝试像这样使用“/socket.io”路径:

var socketio = require('socket.io')(server, 
  serveClient: (config.env === 'production') ? false : true,
  path: '/socket.io'
);

接下来,要选择 websockets 而不是长轮询,您可以在 test-client/scripts/application.js 中选择 websocket 传输

var myIoSocket = window.io.connect('http://localhost:9006', transports:['websocket']);

【讨论】:

天哪,我认为您的第一个建议修复了它(第二个产生了另一个错误)。让我再测试一下。 您好,我认为将“websocket”指定为传输会耗尽电池电量,并导致过度使用 CPU,因为每当我运行我的应用程序时,我的设备都会升温。但就我最近的经验而言,设置“websocket”是在 Heroku 上使用 socket.io 的唯一方法。 @leszek.hanusz 这行得通,但为什么呢?具体来说,我所做的只是添加了传输,它开始正常工作。 sock.io 似乎应该默认使用 websockets 而不是轮询。 @贾斯汀。 “具体来说,我所做的只是添加了传输,它开始正常工作”我认为这个错误已经重新出现......github.com/miguelgrinberg/Flask-SocketIO/issues/…【参考方案2】:

可以尝试两件事: 第一次改变

window.io.connect('http://... 

window.io.connect('ws://...

其次是服务器端设置

socketio.set('transports',['xhr-polling']);

我知道这看起来不正确,因为您想避免投票,但它仍然帮助了很多遇到同样问题的人。

【讨论】:

谢谢!试过了,没用。源代码:github.com/weld-io/socket.io-client-server-boilerplate【参考方案3】:

我认为这是因为您的服务器在http://localhost:9007 上使用套接字,而您的客户端在http://localhost:9006 上使用。尝试将两者放在同一个端口上,它应该可以工作。

【讨论】:

我认为您错过了我的问题中的“客户端和服务器将在两个不同实例上运行的位置”部分。 见上面的新图片。【参考方案4】:

我建议你分别测试客户端-服务器。 nc 将是这种情况的理想替代方案。

    启动服务器和echo testserver | nc server_ip server_port并检查服务器日志。

    启动客户端和netcat -l -p server_port并检查客户端日志。

顺便说一句,您显示的客户端代码似乎没有尝试连接到服务器。

【讨论】:

谢谢。 var myIoSocket = window.io.connect('http://localhost:9006');不是连接语句吗? @TomSöderlund 那么这就是问题所在。您提到您的服务器在 9007 上监听。 @TomSöderlund 我猜你误解了端口和实例。简单地说,端口是您从中接收数据和向其发送数据的地方,这就是它的工作原理。而且它与实例无关。 啊,有趣!那么我应该在上面的代码中进行哪些更改?如果我同时在localhost:9006 上运行,那会破坏客户端或服务器,对吗? @TomSöderlund 这将连接客户端和服务器并且不会破坏它们。

以上是关于Socket.io 无法连接,求助于“轮询”的主要内容,如果未能解决你的问题,请参考以下文章

Socket.IO 客户端在 3g/4g 连接上无法正常工作

连接错误:io.socket.engineio.client.EngineIOException:xhr 轮询错误

Socket.IO 无法通过 https 连接

socket.io 问题。无法连接。前端说连接:假,后端不记录任何东西

socket.io javascript客户端在重新启动服务器后无法重新连接

websocket——通信梳理(短轮询、长轮询、socket、websocket、socket.io)