尝试使用 socket.io 时出错

Posted

技术标签:

【中文标题】尝试使用 socket.io 时出错【英文标题】:getting an error when trying to use socket.io 【发布时间】:2017-02-08 17:19:40 【问题描述】:

我目前正在使用 socket.io swift 客户端。在 iPhone SE 上运行。这是快速代码

 let socket = SocketIOClient(socketURL: URL(string: "http://example.com:4000")!, config: [.log(true), .forcePolling(true)]);
        socket.connect();
        socket.on("connect") data, ack in
            print("socket is connected");
            socket.emit("getData", ["data": 3]);
        

在服务器上:

var express = require('express');
var app = express();
var http = require('http').Server(app);
var io = require('socket.io')(http);

io.on('connection', function(socket)
    console.log('a user connected');
    socket.on('disconnect', function()
        console.log('user disconnected');
    );
    socket.on('getData', function(result)
        console.log(result);
    );
);


app.listen(4000, function () 
  console.log(' on at 4000!');
);

...在 Xcode 控制台上,我得到了

2016-09-29 16:38:33.871895 proj[3070:1019256] LOG SocketEngine: Handshaking
2016-09-29 16:38:33.872301 proj[3070:1019256] LOG SocketEnginePolling: Doing polling request
2016-09-29 16:38:34.004312 proj[3070:1019256] LOG SocketEnginePolling: Got polling response
2016-09-29 16:38:34.004874 proj[3070:1019283] LOG SocketEngine: Got message: Cannot GET /socket.io/?transport=polling&b64=1
2016-09-29 16:38:34.005283 proj[3070:1019283] ERROR SocketIOClient: Got unknown error from server Cannot GET /socket.io/?transport=polling&b64=1

这表明建立了连接并成功找到了服务器,但还有其他问题。 将不胜感激。

【问题讨论】:

【参考方案1】:

(旁注:如果您不需要支持旧浏览器(或任何浏览器,因为您的客户端是本机移动应用程序),那么您可以考虑使用开放标准的 WebSocket。Socket.io 通常是曾经在不支持 WebSocket 的浏览器上具有类似 WebSocket 的功能。另一方面,WebSocket 是一个开放标准,具有广泛的支持(不仅在浏览器中)并且具有更好的性能。有关更多信息,请参阅this answer详细信息。)

现在,既然您已经在使用 Socket.io,那么您可以通过以下方式诊断问题。我会尝试从浏览器连接,这是连接 Socket.io 的主要方式,看看是否可行。如果没有,则意味着您的服务器代码存在问题。如果是这样,则可能意味着您的客户端存在问题。这将是首先要检查的。从那里开始,您可以缩小问题范围并希望解决它。

如果您想从使用 Socket.io 的一些工作代码开始,包括服务器站点 (Node.js) 和客户端(浏览器原生 javascript),那么您可以查看我最初编写的示例this answer,可用on GitHub 和on npm:

Socket.IO 服务器

使用 Express.js 的 Socket.IO 服务器示例:

var path = require('path');
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', (req, res) => 
  console.error('express connection');
  res.sendFile(path.join(__dirname, 'si.html'));
);
io.on('connection', s => 
  console.error('socket.io connection');
  for (var t = 0; t < 3; t++)
    setTimeout(() => s.emit('message', 'message from server'), 1000*t);
);
http.listen(3002, () => console.error('listening on http://localhost:3002/'));
console.error('socket.io example');

来源:https://github.com/rsp/node-websocket-vs-socket.io/blob/master/si.js

Socket.IO 客户端

使用原生 JavaScript 的 Socket.IO 客户端示例:

var l = document.getElementById('l');
var log = function (m) 
    var i = document.createElement('li');
    i.innerText = new Date().toISOString()+' '+m;
    l.appendChild(i);

log('opening socket.io connection');
var s = io();
s.on('connect_error', function (m)  log("error"); );
s.on('connect', function (m)  log("socket.io connection open"); );
s.on('message', function (m)  log(m); );

来源:https://github.com/rsp/node-websocket-vs-socket.io/blob/master/si.html

您可以将相同的代码与 WebSocket 版本进行比较:

WebSocket 服务器

使用 Express.js 的 WebSocket 服务器示例:

var path = require('path');
var app = require('express')();
var ws = require('express-ws')(app);
app.get('/', (req, res) => 
  console.error('express connection');
  res.sendFile(path.join(__dirname, 'ws.html'));
);
app.ws('/', (s, req) => 
  console.error('websocket connection');
  for (var t = 0; t < 3; t++)
    setTimeout(() => s.send('message from server', ()=>), 1000*t);
);
app.listen(3001, () => console.error('listening on http://localhost:3001/'));
console.error('websocket example');

来源:https://github.com/rsp/node-websocket-vs-socket.io/blob/master/ws.js

WebSocket 客户端

使用原生 JavaScript 的 WebSocket 客户端示例:

var l = document.getElementById('l');
var log = function (m) 
    var i = document.createElement('li');
    i.innerText = new Date().toISOString()+' '+m;
    l.appendChild(i);

log('opening websocket connection');
var s = new WebSocket('ws://'+window.location.host+'/');
s.addEventListener('error', function (m)  log("error"); );
s.addEventListener('open', function (m)  log("websocket connection open"); );
s.addEventListener('message', function (m)  log(m.data); );

来源:https://github.com/rsp/node-websocket-vs-socket.io/blob/master/ws.html

我希望这可以帮助您评估是否继续使用 Socket.io 或使用 WebSocket 对您来说是正确的决定,并且会为您提供一些有效的客户端代码来测试您的后端。代码是released under the MIT license(开源、免费软件),所以请随意在您的项目中使用它。

【讨论】:

websocket 不支持哪些浏览器?实际上听起来好多了。你能指出我的快速客户的方向吗?根据我现在阅读的内容,我想我什至可能不会费心留在 socket.io 上。非常感谢深入的回答。 @harrylakins 上次我在this answer 中解释有关 websocket 与 socket.io 的一些误解时做了一些研究,唯一不支持 websocket 的浏览器是opera mini。请参阅caniuse.com/websockets 了解最新信息。 啊,这比它本来可以做的要好得多。关于 swift 客户端的任何想法? 嘿@rsp 我已经阅读了您的一些 SO 答案并查看了您的存储库。做得好。我想知道 socket.io 有什么额外的东西,比如:通过防火墙和防病毒软件建立连接。和自动重新连接。并且还通过传输使用强制 websockets,会更好还是 socket.io 仍然不足? (用例:实时游戏)

以上是关于尝试使用 socket.io 时出错的主要内容,如果未能解决你的问题,请参考以下文章

使用 socket.io 连接到带有套接字的 mysql 数据库时出错

在 Angular 2 应用程序中导入 socket.io-client 时出错 [重复]

Gottox socket.io-java-client“握手时出错”空指针异常

Socket.io + SSL + 自签名 CA 证书在连接时出错

Socket.io 客户端切换到 xhr-polling 时出错

尝试发出时,带有 Node.js 的 Socket.io 在路由文件中返回未定义