Skip to content

Clearing socket.io send buffer after connection timeout #1532

Closed
@TimNZ

Description

@TimNZ

Tip for people who may not be aware of this behaviour.

Below is my code for a browser client.

An unexpected behaviour I just discovered is after the error hooks are called on a socket disconnect, I had presumed that any messages that had failed to be sent during the timeout window were subsequently discarded.

This is not the case - socket.io adds them to a buffer and will resend when the connection is restored.
This is unwanted behaviour as I have already indicated to the user their action has failed e.g. a Signup.

Now I clear the socket.io sendBuffer on connect if detected a disconnect previously

Should this be something Feathers supports via an explicit option, or at least document?

https://stackoverflow.com/questions/32131629/socket-io-stop-re-emitting-event-after-x-seconds-first-failed-attempt-to-get-a-r/32261523#32261523

import io from 'socket.io-client';
import feathers from '@feathersjs/client';
import socketio from '@feathersjs/socketio-client';
import authentication from '@feathersjs/authentication-client';
import paramsForServer from 'feathers-hooks-common/lib/services/params-for-server'
import {CookieStorage} from 'cookie-storage'
const socket = io((window.App && window.App.apiUrl) || window.location.origin, {transports: ['websocket'],
      upgrade: false});
const client = feathers();
let socketDisconnectError = false
socket.on('connect',function() {
  if (socketDisconnectError)
  {
    this.sendBuffer = []
    socketDisconnectError = false
  }
})
client.configure(socketio(socket,{timeout: 30000})); 
client.configure(authentication({
  storage: new CookieStorage({path: '/',expires: new Date().addDays(7) }),
  service: 'service/users'
}));
client.paramsForServer = paramsForServer
client.on('server.connection.error',(context) => {
  console.log('server.connection.error',context)
  // TODO: Send notification elsewhere that couldn't connect to the server

})
const ErrorMessageReplaces = [[/Timeout of/i,'Sorry.  We were unable to connect to our server or got no response.  Please try again later.']]

const processTransportErrors = (context) => {
  ErrorMessageReplaces.forEach((pair,i) => {
    if (context.error.message.match(pair[0]))
    {

      context.error.message = pair[1];
      context.app.emit('server.connection.error',context)
      socketDisconnectError = true
      return false;
    }
  })
  return context;

}

client.hooks({
  error: {
    all: [processTransportErrors]
  }
})


export default client;

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions