WebSocket客户端到Socket.IO的转换

12
我需要一个服务器能够接受来自websocket和socket.io客户端的连接,这是可能的吗?当我只运行socket.io时,socket.io客户端可以正常工作,但标准的websocket客户端无法连接。另一方面,当我同时运行websocket服务器和socket.io时,websocket也能正常工作,但在浏览器中,通过socket.io尝试连接时,我看到错误消息 WebSocket connection to ... failed: Invalid frame header。是否可能在单个服务器实例上使两个连接都正常工作?
我正在使用express.iowebsocket-node,如果能只用express.oi就能使其工作将会很棒。

为什么需要这样做?socket.io是在webSocket之上的一个附加协议,因此您不能使用相同的服务器端代码来同时监听纯webSocket和socket.io连接。最简单的方法是将其中一个连接放在不同的端口上,并为每个连接使用不同的处理程序,让每个标准库处理它们所构建的内容。 - jfriend00
2个回答

21

虽然 @jfriend00 是正确的,socket.io 是在 WebSocket 之上的附加协议,但我发现这个附加协议可能相当简单。我认为 socket.io@2.0.3 服务器隐式运行了由 ws@2.3.1 提供支持的 WebSocket 服务器,我成功地(借助 F12/network 工具的帮助)使用原生 WebSocket 客户端连接到它。

socket.io 客户端:

var socket = io('http://localhost');
socket.emit('hello', 'there');

WebSocket客户端:

var ws = new WebSocket('ws://localhost/socket.io/?EIO=3&transport=websocket');
ws.send('42' + JSON.stringify(['hello', 'there']));
// ws.onmessage will get a MessageEvent object with the data property being encoded in the similar way.

Socket.IO API 更加抽象,它处理事件和参数,而 WebSocket API 处理字符串。


2
ws.send('42'... 是什么意思?这里的 42 有必要吗? - Mobilpadde
3
@Mobilpadde 是的,我认为这个数字是某种消息类型。如果我没记错的话,还有至少一个数字,代表“探测”消息。 - Zhiyong
2
@Mobilpadde 你可以自己看一下:在Chrome中打开https://socket.io/demos/chat/,然后在F12 > 网络中,使用“EIO=3&transport=websocket”进行过滤,应该会有一些结果,响应头应包含“Connection:upgrade”,详细面板中应该有“Frames”选项卡,而不是普通HTTP请求的“Preview”和“Response”选项卡。在“Frames”选项卡中列出的内容相当直观,例如'2probe','42["login", {numUsers: 10}]'。我认为浏览器支持的是websocket,即升级后的HTTP,而不是Socket.IO。 - Zhiyong
3
42是万物的答案。 - cevaris
1
  • 4 是 Engine.IO 的 "message" 数据包类型
  • 2 是 Socket.IO 的 "message" 数据包类型
https://socket.io/docs/v4/#is-socketio-still-needed-today
- undefined
显示剩余2条评论

1

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