2

使用 ws,Node.js WebSocket 库,可以让多个服务器共享一个 HTTP/S 服务器

是否可以对 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。

4

1 回答 1

3

您可以将两个 socket.io 服务器连接到同一个 Web 服务器。为了使其工作,每个 socket.io 实例需要位于不同的路径上(一个可以是默认路径,一个可以是自定义路径)。这意味着您需要path在 socket.io 客户端和 socket.io 服务器中设置选项以匹配其中一台服务器。

请记住,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/#带有自定义路径


如果您真的只是想分离传入的 socket.io 连接,但实际上不必有两个单独的 socket.io 服务器实例,您可以使用 socket.io 命名空间来做到这一点。每个客户端都将连接到不同的命名空间(其工作方式类似于路径,但它不是真正的路径),然后您可以在服务器端为每个命名空间上的传入连接设置单独的侦听器。这是 socket.io 在 webSocket 之上添加的一个特性,正是针对这种情况。

于 2020-02-02T22:06:58.287 回答