为什么 HTML WebSocket 无法访问 Socket.io 的 web socket 服务器?

4
如 socket.io 所述,它支持 WebSocket。因此,我使用 HTML5 标准的 Web Socket API 访问 socket.io 服务器,但总是遇到以下错误:
WebSocket 连接 ws://localhost:8080/ 失败:在接收握手响应前连接已关闭。
然后,我尝试使用 js 中的 socket.io 客户端访问 socket.io 服务器,它可以正常工作,并且通过 Chrome 网络监视器,我发现它正确地使用了 Web Socket 协议。
有人曾经尝试使用 W3C Websocket API 访问 socket.io 服务器并遇到类似的问题吗?或者对我的问题有任何想法或线索?感激不尽!
测试代码在这里:https://github.com/piginzoo/socketiotest

现在我正在使用socket.io 0.9来适配AndroidASync项目,它目前只支持socket.io 0.9。 - piginzoo
在Chrome和IE-11上遇到了完全相同的问题。后者会给出更具体的错误信息:“WebSocket Error: Network Error 12152,服务器返回无效或未被识别的响应”。看起来socket.io实际上与Chrome或IE-11实现的Websocket API不太兼容。 - Alex
3个回答

2
注意:Socket.IO不是WebSocket实现。虽然Socket.IO确实在可能的情况下使用WebSocket作为传输,但它会向每个数据包添加一些元数据:数据包类型、命名空间和当需要消息确认时的ack id。这就是为什么WebSocket客户端无法成功连接到Socket.IO服务器,而Socket.IO客户端也无法连接到WebSocket服务器(如ws://echo.websocket.org)。
我在Socket.IO的GitHub问题中发现了以下信息:
Socket.IO不是WebSocket服务器。请参见ws https://github.com/socketio/socket.io/issues/3022

1
你得到的错误信息是因为你使用了错误的URL。错误信息“在收到握手响应之前关闭连接”实际上告诉了你这一点(没有收到响应)。
正确的URL应该是'ws://localhost:8080/socket.io/?EIO=3&transport=websocket'。详情请参见https://socket.io/docs/client-api/#With-custom-pathhttps://socket.io/docs/internals/
例如:
"EIO=3"               # the current version of the Engine.IO protocol

但是,正如其他答案所说,实际上这就是socket.io自述文件所说的:

尽管Socket.IO在可能的情况下确实使用WebSocket作为传输协议,但它会向每个数据包添加一些元数据:数据包类型、名称空间和当需要消息确认时的确认ID。这就是为什么WebSocket客户端无法成功连接到Socket.IO服务器,而Socket.IO客户端也无法连接到WebSocket服务器的原因。

我已经测试过了,验证了ws和浏览器本地Websocket都无法连接到Socket.IO服务器。它们连接后立即从Socket.IO服务器断开连接,并且Socket.IO服务器发送出错误消息socket id xxx has disconnected with reason parse error

ws作者在这里也提到了https://github.com/websockets/ws/issues/1390

使用普通的WebSocket与Socket.IO服务器进行通信并不完美。

如果您想使用浏览器原生Websocket,可以使用ws作为服务器。

0

我们曾经遇到过完全相同的问题。最终采用了ws WebSocket。不确定是否有更好的解决方案。


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