apollographql / graphql-subscriptions

:newspaper: A small module that implements GraphQL subscriptions for Node.js
MIT License
1.58k stars 133 forks source link

SubId in custom asyncIterator wrapper #225

Closed ftabarie closed 4 years ago

ftabarie commented 4 years ago

Hi guys,

A little of context, I have an Apollo UI, realtime thanks to my Graphql API subscriptions, and I have sometimes massive events coming to my UI ( it can be 500/sec ).

To avoid the UI to be spamed by the subscriptions events, I decided to create a custom asyncIterator wrapper API side, to throttle the events ( when I have a new event I put it in a buffer, wait 5 secondes, during theses 5secondes, I merge every events, then after this delay I send them, then reproduce this strategy )

Everything is working well, but, when I have many subscribers for the same subscription, only the first subscriber will receive the buffer data, because I reset the buffer after sending the data, so others subscribers will received an empty buffer.

So if they subscribe to the same subscription im fckd.

To avoid this, I just need to have a buffer by subscription x subscriber, but in the 4 variables ( RootValue, args, context, info ) I have in the asyncIterator wrapper, I dont have the subscriptor Id

in the 4th arguments ( info ) I have a lot of datas, but I didnt find any subscriptor Id

Do you know if we have this information in the wrapper ?

TLDR: where can I find a client/subscriber Id ?

ftabarie commented 4 years ago

I did a trick, for thoses who are interested:

I added subscriptions to ApolloServer options, to inject in the context the websocket key as socketId, then I can retrieve it into the 3rd argument context

const server = new ApolloServer({
    ...apolloOptions,
    subscriptions: {
      onConnect: (_, webSocket) => {
        return { socketId: webSocket.upgradeReq.headers['sec-websocket-key'] }
      }
    }
  })