有了ws,Node.js WebSocket库,就有了multiple servers sharing a single HTTP/S server。
是否可以对socket.io做同样的事情?
我需要在同一HTTP服务器上有两个WebSocket服务器,一个用于socket.io,另一个用于Apollo订阅。我可以使用Websocket服务器设置Apollo订阅服务器,但不能为socket.io设置,socket.io仅接受HTTP服务器。
我想做这样的事情:
const socketioWsS = new WebSocket.Server({ noServer: true });
const graphqlWsS = new WebSocket.Server({ noServer: true });
const io = socketIo(socketioWsS, {
transports: ["websocket"]
});
server.on("upgrade", function upgrade(request, socket, head) {
const pathname = url.parse(request.url).pathname;
if (pathname === "/socket.io/") {
socketioWsS.handleUpgrade(request, socket, head, function done(ws) {
socketioWsS.emit("connection", ws, request);
});
} else if (pathname === "/graphql") {
graphqlWsS.handleUpgrade(request, socket, head, function done(ws) {
graphqlWsS.emit("connection", ws, request);
});
} else {
socket.destroy();
}
});
server.listen(config.app.port, () => {
...
new SubscriptionServer(
{
execute,
subscribe,
schema
},
{
server: graphqlWsS
}
);
});
它对于Graphql订阅非常有效,但对socket.io则不起作用。
答案 0 :(得分:2)
您可以将两个socket.io服务器连接到同一Web服务器。为了使其正常工作,每个socket.io实例都必须位于不同的路径上(一个可以是默认路径,一个可以是自定义路径)。这意味着您需要在socket.io客户端和socket.io服务器中都设置path
选项以匹配其中一台服务器。
请记住,socket.io的客户端和服务器中的默认路径(如果未指定任何内容)为/socket.io
,这就是为什么它响应/socket.io/socket.io.js
来提供客户端的原因socket.io客户端代码。因此,如果您同时更改了两者的路径,则必须调整客户端获取其socket.io代码的方式。
以下是用于在服务器端设置路径的文档:https://socket.io/docs/server-api/,而这是客户端的文档:https://socket.io/docs/client-api/#With-custom-path。
如果您确实只想分离传入的socket.io连接,但实际上不必具有两个单独的socket.io服务器实例,则可以使用socket.io命名空间来实现。每个客户端将连接到一个不同的名称空间(其工作方式类似于路径,但实际上不是路径),然后您可以在服务器端为每个名称空间上的传入连接设置单独的侦听器。正是在这种情况下,socket.io在webSocket之上添加了此功能。