6

別の Websocket サーバーsocket.ioを別のパスで動作させる方法はありますか?

let http = require('http');
let express = require('express');
let socketio = require('socket.io');
let websocket = require('ws');

let httpServer = http.createServer();

let expressApp = express();
httpServer.on('request', expressApp);

let socketioServer = socketio(httpServer, { path: '/aaaaa/socket.io/' });
socketioServer.of('/').on('connect', () => {});

let websocketServer = new websocket.Server({ server: httpServer, path: '/aaaaa/graphql' });

httpServer.listen(2233, () => console.log('started'));

私が見ている動作は、別の websocket サーバーが作成された場合socket.ioでも適切に機能しますが、websocket への接続をアップグレードせず、(chrome から) エラーで失敗することです:

WebSocket connection to 'ws://localhost:2233/aaaaa/socket.io/?EIO=3&transport=websocket&sid=fx4pOT0cegz65JMCAAAB' failed: Invalid frame header

明確にするために、websocket server 行が省略されている場合、socket.io正常に動作します。

apollo-server-express私の具体的なユースケースは、サブスクリプションが有効になっているときにパッケージによって websocket サーバーが作成されることです。socket.ioより使いやすい方法で構成する方法はありますか? または、作成する代わりに apollo が使用する Websocket サーバーを提供できると思います...どのように作成しますか?

再現用のパッケージ バージョン:

node       8.11.1
express    4.16.4
socket.io  2.1.1
ws         6.1.0
4

2 に答える 2

2

これが他の誰かに役立つ場合、ここに私の派生ソリューションがあります:

let [socketioUpgradeListener, apolloUpgradeListener] = httpServer.listeners('upgrade').slice(0);
httpServer.removeAllListeners('upgrade');
httpServer.on('upgrade', (req, socket, head) => {
  const pathname = url.parse(req.url).pathname;
  if (pathname == '/aaaaa/socket.io/')
    socketioUpgradeListener(req, socket, head);
  else if (pathname == '/aaaaa/graphql')
    apolloUpgradeListener(req, socket, head);
  else
    socket.destroy();
});

どちらのライブラリも、私がそれらをいじる前に、多数のイベント リスナーを使用して Websocket サーバーを完全に初期化していたため、少し面倒でした。ただし、'upgrade'リスナーを選択して手動で委任することはできました。もちろん、これは初期化の順序と新しいリスナーに敏感であるため、完璧ではありませんが、私のユースケースには十分です。

このソリューションに明らかな欠陥がある場合、または websocket サーバー委任に関するその他のニュアンスがある場合は、お知らせください。

于 2018-11-07T00:16:29.263 に答える