Closed
Description
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?
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;