Skip to content

Commit 2a746d6

Browse files
authored
Send a close to all websocket connections when server closes (#46)
1 parent a5dbfe9 commit 2a746d6

File tree

2 files changed

+57
-1
lines changed

2 files changed

+57
-1
lines changed

index.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,18 @@ function fastifyWebsocket (fastify, opts, next) {
6666

6767
fastify.addHook('onClose', close)
6868

69+
// Fastify is missing a pre-close event, or the ability to
70+
// add a hook before the server.close call. We need to resort
71+
// to monkeypatching for now.
72+
const oldClose = fastify.server.close
73+
fastify.server.close = function (cb) {
74+
const server = fastify.websocketServer
75+
for (const client of server.clients) {
76+
client.close()
77+
}
78+
oldClose.call(this, cb)
79+
}
80+
6981
function handleRouting (connection, request) {
7082
const response = new ServerResponse(request)
7183
request[kWs] = WebSocket.createWebSocketStream(connection)
@@ -77,7 +89,8 @@ function fastifyWebsocket (fastify, opts, next) {
7789
}
7890

7991
function close (fastify, done) {
80-
fastify.websocketServer.close(done)
92+
const server = fastify.websocketServer
93+
server.close(done)
8194
}
8295

8396
module.exports = fp(fastifyWebsocket, {

test/base.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,3 +144,46 @@ test('Should throw on an invalid handle parameter', (t) => {
144144
t.equal(err.message, 'invalid handle function')
145145
})
146146
})
147+
148+
test('Should gracefully close with a connected client', (t) => {
149+
t.plan(6)
150+
151+
const fastify = Fastify()
152+
153+
fastify.register(fastifyWebsocket, { handle })
154+
155+
function handle (connection) {
156+
connection.setEncoding('utf8')
157+
connection.write('hello client')
158+
159+
connection.once('data', (chunk) => {
160+
t.equal(chunk, 'hello server')
161+
})
162+
163+
connection.on('end', () => {
164+
t.pass('end emitted on server side')
165+
})
166+
// this connection stays alive untile we close the server
167+
}
168+
169+
fastify.listen(0, (err) => {
170+
t.error(err)
171+
172+
const ws = new WebSocket('ws://localhost:' + fastify.server.address().port)
173+
const client = WebSocket.createWebSocketStream(ws, { encoding: 'utf8' })
174+
175+
client.setEncoding('utf8')
176+
client.write('hello server')
177+
178+
client.on('end', () => {
179+
t.pass('end emitted on client side')
180+
})
181+
182+
client.once('data', (chunk) => {
183+
t.equal(chunk, 'hello client')
184+
fastify.close(function (err) {
185+
t.error(err)
186+
})
187+
})
188+
})
189+
})

0 commit comments

Comments
 (0)