Skip to content

Commit

Permalink
fix(socketio): Disconnect socket on app disconnect event (#2896)
Browse files Browse the repository at this point in the history
  • Loading branch information
daffl authored Nov 27, 2022
1 parent 9db5e7a commit 4ba0039
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 7 deletions.
6 changes: 3 additions & 3 deletions packages/socketio/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import http from 'http'
import { Server, ServerOptions } from 'socket.io'
import { createDebug } from '@feathersjs/commons'
import { Application } from '@feathersjs/feathers'
import { Application, RealTimeConnection } from '@feathersjs/feathers'
import { socket } from '@feathersjs/transport-commons'

import { disconnect, params, authentication, FeathersSocket } from './middleware'
Expand Down Expand Up @@ -42,7 +42,7 @@ function configureSocketio(port?: any, options?: any, config?: any) {
// Function that gets the connection
const getParams = (socket: FeathersSocket) => socket.feathers
// A mapping from connection to socket instance
const socketMap = new WeakMap()
const socketMap = new WeakMap<RealTimeConnection, FeathersSocket>()
// Promise that resolves with the Socket.io `io` instance
// when `setup` has been called (with a server)
const done = new Promise((resolve) => {
Expand All @@ -67,7 +67,7 @@ function configureSocketio(port?: any, options?: any, config?: any) {
if (!this.io) {
const io = (this.io = new Server(port || server, options))

io.use(disconnect(app, getParams))
io.use(disconnect(app, getParams, socketMap))
io.use(params(app, socketMap))
io.use(authentication(app, getParams))

Expand Down
21 changes: 17 additions & 4 deletions packages/socketio/src/middleware.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Application, Params } from '@feathersjs/feathers'
import { Application, Params, RealTimeConnection } from '@feathersjs/feathers'
import { createDebug } from '@feathersjs/commons'
import { Socket } from 'socket.io'

Expand All @@ -10,14 +10,27 @@ export interface FeathersSocket extends Socket {
feathers?: Params & { [key: string]: any }
}

export const disconnect =
(app: Application, getParams: ParamsGetter) => (socket: FeathersSocket, next: NextFunction) => {
export const disconnect = (
app: Application,
getParams: ParamsGetter,
socketMap: WeakMap<RealTimeConnection, FeathersSocket>
) => {
app.on('disconnect', (connection: RealTimeConnection) => {
const socket = socketMap.get(connection)
if (socket && socket.connected) {
socket.disconnect()
}
})

return (socket: FeathersSocket, next: NextFunction) => {
socket.on('disconnect', () => app.emit('disconnect', getParams(socket)))
next()
}
}

export const params =
(_app: Application, socketMap: WeakMap<any, any>) => (socket: FeathersSocket, next: NextFunction) => {
(_app: Application, socketMap: WeakMap<RealTimeConnection, FeathersSocket>) =>
(socket: FeathersSocket, next: NextFunction) => {
socket.feathers = {
provider: 'socketio',
headers: socket.handshake.headers
Expand Down
12 changes: 12 additions & 0 deletions packages/socketio/test/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,18 @@ describe('@feathersjs/socketio', () => {
assert.ok(mySocket)
})

it('app `disconnect` event disconnects socket (#2754)', (done) => {
const mySocket = io('http://localhost:7886?channel=dctest')

app.once('connection', (connection) => {
assert.strictEqual(connection.channel, 'dctest')
mySocket.once('disconnect', () => done())
app.emit('disconnect', connection)
})

assert.ok(mySocket)
})

it('missing parameters in socket call works (#88)', (done) => {
socket.emit('find', 'verify', (error: any, data: any) => {
assert.ok(!error)
Expand Down

0 comments on commit 4ba0039

Please sign in to comment.