Subscriptions-transport-ws: Multiple schemas on different endpoins

Created on 1 Jul 2017  路  2Comments  路  Source: apollographql/subscriptions-transport-ws

Hi,

I have multiple schemas in my application for a multitenant app.

I have code that is something like

SubscriptionServer.create(
  {
    execute,
    subscribe,
    schema: schema1,
  },
  {
    path: `/graphql/test1`,
    server
  }
);
SubscriptionServer.create(
  {
    execute,
    subscribe,
    schema: schema2
  },
  {
    path: `/graphql/test2`,
    server
  }
);

However once I add in another endpoint the client will fail to connect. I will get the error WebSocket connection to 'ws://localhost:4000/graphql/test1' failed: Invalid frame header.

Is there any sort of work around for this?

waiting-for-response

Most helpful comment

Hey @Anthonyzou could you please try the suggested official way from ws (https://github.com/websockets/ws/pull/885)?

so it will be something like:

const server = http.createServer();
const wsServer1 = SubscriptionServer.create(
  {
    execute,
    subscribe,
    schema: schema1,
  },
  {
    noServer: true
  }
);
const wsServer2 = SubscriptionServer.create(
  {
    execute,
    subscribe,
    schema: schema2
  },
  {
    noServer: true
  }
);

server.on('upgrade', (request, socket, head) => {
  const pathname = url.parse(request.url).pathname;

  if (pathname === '/graphql/test1') {
    wsServer1.wsServer.handleUpgrade(request, socket, head, (ws) => {
      wsServer1.wsServer.emit('connection', ws);
    });
  } else if (pathname === '/graphql/test2') {
    wsServer2.wsServer.handleUpgrade(request, socket, head, (ws) => {
      wsServer2.wsServer.emit('connection', ws);
    });
  } else {
    socket.destroy();
  }
});

Let me know if it worked.

All 2 comments

Hey @Anthonyzou could you please try the suggested official way from ws (https://github.com/websockets/ws/pull/885)?

so it will be something like:

const server = http.createServer();
const wsServer1 = SubscriptionServer.create(
  {
    execute,
    subscribe,
    schema: schema1,
  },
  {
    noServer: true
  }
);
const wsServer2 = SubscriptionServer.create(
  {
    execute,
    subscribe,
    schema: schema2
  },
  {
    noServer: true
  }
);

server.on('upgrade', (request, socket, head) => {
  const pathname = url.parse(request.url).pathname;

  if (pathname === '/graphql/test1') {
    wsServer1.wsServer.handleUpgrade(request, socket, head, (ws) => {
      wsServer1.wsServer.emit('connection', ws);
    });
  } else if (pathname === '/graphql/test2') {
    wsServer2.wsServer.handleUpgrade(request, socket, head, (ws) => {
      wsServer2.wsServer.emit('connection', ws);
    });
  } else {
    socket.destroy();
  }
});

Let me know if it worked.

Thanks @mistic it works except for the fact emit of connection should provide request as well,
also, wsServer is private so need to access it using
so wsServerX['wsServer'].emit('connection', ws, req)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

PetrSnobelt picture PetrSnobelt  路  3Comments

prokher picture prokher  路  5Comments

nickofthyme picture nickofthyme  路  3Comments

AruXc picture AruXc  路  3Comments

altschuler picture altschuler  路  4Comments