我用Node&创建了一个简单的服务器Socket.io在/my-namespace
下声明了一个名称空间。一旦有人连接,发出确认消息为CONNECT_ACK
并在3秒后发出另一个事件(例如SOME_EVENT
)并带有有效负载:
const express = require('express');
const http = require('http');
const socketIO = require('socket.io');
let app = express();
let server = http.createServer(app);
server.listen(3000, () => {
console.log('server listening on port 3000');
let io = new socketIO(server);
io.of('/my-namespace').on('connection', (socket) => {
console.log('welcome!');
socket.emit('CONNECT_ACK');
setTimeout(() => {
io.of('/my-namespace').emit('SOME_EVENT', { a: 4 });
}, 3000);
});
});
然后,我创建了最小的客户端,它只是连接到命名空间并在收到CONNECT_ACK
或SOME_EVENT
<!doctype html>
<html>
<head>
<title>example</title>
<script src="./node_modules/socket.io-client/socket.io.js"></script>
<script>
const endPoint = "http://localhost:3000/my-namespace";
io(endPoint)
.on('CONNECT_ACK', () => { console.log("I've connected"); })
.on('SOME_EVENT', (data) => { console.dir(data); });
</script>
</head>
<body>
</body>
</html>
运行客户端node index.js
并提供html(我使用Python Simple Server)我在两个控制台中都得到了所需:
现在,当我打开Network
Chrome标签时,我开始撰写这篇长篇文章。这些是请求:
/socket.io
(不是 /my-channel
)接收一些确认位;再次POST到/socket.io
,包括那些确认位。行。/socket.io
获取GET,其中包含现在已解析为CONNECT_ACK
事件的确认位:ÿ40ÿ40/my-namespaceÿ42/my-namespace,["CONNECT_ACK"]
。这是我将以这种方式接收的唯一事件。/socket.io
表示它是一个websoket给我一个101(切换协议),我可以收到msgs:42/my-namespace,["SOME_EVENT",{"a":4}]
这是我从服务器发送的事件&amp;有些2
或3
定期/socket.io
获取GET,其中包含现在已解决此问题的确认位:ÿ6
socket.io
而不是/my-channel
?CONNECT_ACK
msg的WS握手之后有 ?2
和3
只是定期检查。 42
开头(我已经检查过这不会改变)答案 0 :(得分:1)
为什么客户要求
socket.io
而不是/my-channel
?
设置socket.io-server
时,socket.io会将自己设置为拦截对/socket.io
的任何请求以便工作。命名空间使用与HTTP中的路径相同的符号,但意味着完全不同的东西,并且连接到命名空间会对/socket.io
执行相同的HTTP请求,但其中包含不同的命名空间参数。
为什么在WS握手之后有一个接收到CONNECT_ACK消息的GET?
我无法确定这一点,但这可能在 WS请求之前到达服务器,并通过轮询发送CONNECT_ACK
。
为什么所有事件都以42开始(我已经检查过这不会改变)
根据this GitHub issue,它将数据包定义为类型message
(4
)的event
(2
)。就个人而言,我怀疑4
实际上是协议版本,目前是4
,因为除了数据包类型(必须是{{1)之外,它是文档中唯一对该数字的引用。 }})。
最终的GET是什么?它是WS协议的一部分吗?
不确定,但是可能确认已经建立了WS连接,并且socket.io确认它应该从轮询切换到WS并开始在那里发送事件。< / p>