pladaria / reconnecting-websocket

Reconnecting WebSocket. For Web, React Native, cli (Node.js)
MIT License
1.23k stars 199 forks source link

Change add/remove listeners so that it defaults to existing function rather than param #136

Open GavinRay97 opened 4 years ago

GavinRay97 commented 4 years ago

It would be nice if the this._addListeners() and this._removeListeners() could cache the current functions for open, message, error, etc, and use those as a backup.

const handleOpen = this._handleOpen || previousHandleOpen
this._ws.addEventListener('open', handleOpen);

The reason why is because when using another library on top, like websocket-as-promised, it registers the handlers but doesn't directly do it through .addEventListener() so they get removed after the first re-connect:

const socketFactory = (url) =>
  const socket = new ReconnectingWebsocket(url, ['graphql-ws'], {
    WebSocket: WebSocket,
    debug: true
  })
  // Listeners added HERE will work after re-connect
  socket.addEventListener('message', (e) => {})
  return socket
}

// But if we use a wrapping library
const socket = new WebSocketAsPromised(this.config.endpoint, {
  createWebSocket: (url) => socketFactory(url),
  extractMessageData: (event) => event,
  packMessage: (data) => JSON.stringify(data),
  unpackMessage: ({data}) => JSON.parse(data as string),
} as any)

// And set listeners this way, they won't work after reconnect
socket.onMessage.addListener((data) => {
  console.log('Socket id', id, 'got message', data)
})
socket.onClose.addListener(() => {
  console.log('Socket id', id, 'closed')
})
socket.onOpen.addListener(() => {
  console.log('Socket id', id, 'opened')
})

You can see this happening here ([Function: listener] are the lower 3 functions, the [Function] without listener is the one set with addEventListener and it's the only one that remains):

image