UNPKG

3.15 kBPlain TextView Raw
1import http from 'http'
2import { Server, ServerOptions } from 'socket.io'
3import { createDebug } from '@feathersjs/commons'
4import { Application, RealTimeConnection } from '@feathersjs/feathers'
5import { socket } from '@feathersjs/transport-commons'
6
7import { disconnect, params, authentication, FeathersSocket } from './middleware'
8
9const debug = createDebug('@feathersjs/socketio')
10
11declare module '@feathersjs/feathers/lib/declarations' {
12 // eslint-disable-next-line @typescript-eslint/no-unused-vars
13 interface Application<Services, Settings> {
14 io: any
15 listen(options: any): Promise<http.Server>
16 }
17}
18
19function configureSocketio(callback?: (io: Server) => void): (app: Application) => void
20function configureSocketio(
21 options: number | Partial<ServerOptions>,
22 callback?: (io: Server) => void
23): (app: Application) => void
24function configureSocketio(
25 port: number,
26 options?: Partial<ServerOptions>,
27 callback?: (io: Server) => void
28): (app: Application) => void
29function configureSocketio(port?: any, options?: any, config?: any) {
30 if (typeof port !== 'number') {
31 config = options
32 options = port
33 port = null
34 }
35
36 if (typeof options !== 'object') {
37 config = options
38 options = {}
39 }
40
41 return (app: Application) => {
42 // Function that gets the connection
43 const getParams = (socket: FeathersSocket) => socket.feathers
44 // A mapping from connection to socket instance
45 const socketMap = new WeakMap<RealTimeConnection, FeathersSocket>()
46 // Promise that resolves with the Socket.io `io` instance
47 // when `setup` has been called (with a server)
48 const done = new Promise((resolve) => {
49 const { listen, setup } = app as any
50
51 Object.assign(app, {
52 async listen(this: any, ...args: any[]) {
53 if (typeof listen === 'function') {
54 // If `listen` already exists
55 // usually the case when the app has been expressified
56 return listen.call(this, ...args)
57 }
58
59 const server = http.createServer()
60
61 await this.setup(server)
62
63 return server.listen(...args)
64 },
65
66 async setup(this: any, server: http.Server, ...rest: any[]) {
67 if (!this.io) {
68 const io = (this.io = new Server(port || server, options))
69
70 io.use(disconnect(app, getParams, socketMap))
71 io.use(params(app, socketMap))
72 io.use(authentication(app, getParams))
73
74 // In Feathers it is easy to hit the standard Node warning limit
75 // of event listeners (e.g. by registering 10 services).
76 // So we set it to a higher number. 64 should be enough for everyone.
77 io.sockets.setMaxListeners(64)
78 }
79
80 if (typeof config === 'function') {
81 debug('Calling SocketIO configuration function')
82 config.call(this, this.io)
83 }
84
85 resolve(this.io)
86
87 return setup.call(this, server, ...rest)
88 }
89 })
90 })
91
92 app.configure(
93 socket({
94 done,
95 socketMap,
96 getParams,
97 emit: 'emit'
98 })
99 )
100 }
101}
102
103export = configureSocketio