问题
With ws, Node.js WebSocket library, it is possible to have multiple servers sharing a single HTTP/S server.
Is it possible to do the same with socket.io?
I need to have two WebSocket servers on the same HTTP server, one for socket.io and another one for Apollo subscriptions. I can set up Apollo subscription server with a Websocket server but not for socket.io, socket.io only accepts HTTP server.
I thought in doing something like this:
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
}
);
});
It works well for Graphql subscriptions, but it does not work for socket.io.
回答1:
You can have two socket.io servers attached to the same web server. To make it work, each socket.io instance needs to be on a different path (one can be the default path and one can be custom). That means you need to set the path
option in both socket.io client and socket.io server to match for one of the servers.
Keep in mind that the default path in both client and server (if you don't specify anything) for socket.io is /socket.io
and that is why it responds to /socket.io/socket.io.js
to give the client the socket.io client code. So, if you change the path on both, you will have to adjust how the client gets its socket.io code.
Here's the doc for setting the path on the server-side: https://socket.io/docs/server-api/ and here's the client-side doc: https://socket.io/docs/client-api/#With-custom-path.
If you really just want to separate out the incoming socket.io connections, but don't really have to have two separate socket.io server instances, you can do that using socket.io namespaces. Each client would connect to a different namespace (which works like a path, but it isn't really a path) and then you can have separate listeners on the server-side for incoming connections on each namespace. This is a feature that socket.io adds on top of webSocket precisely for circumstances like this.
来源:https://stackoverflow.com/questions/60029843/multiple-socket-io-servers-sharing-a-single-http-s-server