Skip to content

Commit 0a0d00f

Browse files
mcollinajsumners
andauthored
Update to Fastify v4 (#197)
* Update to Fastify v4 Signed-off-by: Matteo Collina <[email protected]> * Updated README * dropped old nodes Signed-off-by: Matteo Collina <[email protected]> * ignore else line Signed-off-by: Matteo Collina <[email protected]> * Fixed test/hooks * ignore lines Signed-off-by: Matteo Collina <[email protected]> * Fixed tests (maybe) * Update README.md Co-authored-by: James Sumners <[email protected]> Co-authored-by: James Sumners <[email protected]>
1 parent ef8986a commit 0a0d00f

File tree

8 files changed

+593
-560
lines changed

8 files changed

+593
-560
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,9 @@ jobs:
1414
strategy:
1515
matrix:
1616
node-version:
17-
- 10
18-
- 12
1917
- 14
2018
- 16
19+
- 18
2120
os:
2221
- macos-latest
2322
- ubuntu-latest

README.md

Lines changed: 39 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,12 @@ After registering this plugin, you can choose on which routes the WS server will
3333

3434
const fastify = require('fastify')()
3535
fastify.register(require('@fastify/websocket'))
36-
37-
fastify.get('/', { websocket: true }, (connection /* SocketStream */, req /* FastifyRequest */) => {
38-
connection.socket.on('message', message => {
39-
// message.toString() === 'hi from client'
40-
connection.socket.send('hi from server')
36+
fastify.register(async function (fastify) {
37+
fastify.get('/', { websocket: true }, (connection /* SocketStream */, req /* FastifyRequest */) => {
38+
connection.socket.on('message', message => {
39+
// message.toString() === 'hi from client'
40+
connection.socket.send('hi from server')
41+
})
4142
})
4243
})
4344

@@ -62,18 +63,19 @@ fastify.register(require('@fastify/websocket'), {
6263
options: { maxPayload: 1048576 }
6364
})
6465

65-
66-
fastify.get('/*', { websocket: true }, (connection /* SocketStream */, req /* FastifyRequest */) => {
67-
connection.socket.on('message', message => {
68-
// message.toString() === 'hi from client'
69-
connection.socket.send('hi from wildcard route')
66+
fastify.register(async function (fastify) {
67+
fastify.get('/*', { websocket: true }, (connection /* SocketStream */, req /* FastifyRequest */) => {
68+
connection.socket.on('message', message => {
69+
// message.toString() === 'hi from client'
70+
connection.socket.send('hi from wildcard route')
71+
})
7072
})
71-
})
7273

73-
fastify.get('/', { websocket: true }, (connection /* SocketStream */, req /* FastifyRequest */) => {
74-
connection.socket.on('message', message => {
75-
// message.toString() === 'hi from client'
76-
connection.socket.send('hi from server')
74+
fastify.get('/', { websocket: true }, (connection /* SocketStream */, req /* FastifyRequest */) => {
75+
connection.socket.on('message', message => {
76+
// message.toString() === 'hi from client'
77+
connection.socket.send('hi from server')
78+
})
7779
})
7880
})
7981

@@ -127,11 +129,10 @@ This plugin uses the same router as the `fastify` instance, this has a few impli
127129
- When using `@fastify/websocket`, it needs to be registered before all routes in order to be able to intercept websocket connections to existing routes and close the connection on non-websocket routes.
128130

129131
```js
130-
'use strict'
131-
132-
const fastify = require('fastify')()
132+
import Fastify from 'fastify'
133133

134-
fastify.register(require('@fastify/websocket'))
134+
const fastify = Fastify()
135+
await fastify.register(require('@fastify/websocket'))
135136

136137
fastify.get('/', { websocket: true }, function wsHandler (connection, req) {
137138
// bound to fastify server
@@ -143,12 +144,7 @@ fastify.get('/', { websocket: true }, function wsHandler (connection, req) {
143144
})
144145
})
145146

146-
fastify.listen(3000, err => {
147-
if (err) {
148-
fastify.log.error(err)
149-
process.exit(1)
150-
}
151-
})
147+
await fastify.listen({ port: 3000 })
152148
```
153149

154150
If you need to handle both HTTP requests and incoming socket connections on the same route, you can still do it using the [full declaration syntax](https://www.fastify.io/docs/latest/Routes/#full-declaration), adding a `wsHandler` property.
@@ -167,22 +163,24 @@ fastify.register(require('@fastify/websocket'), {
167163
options: { maxPayload: 1048576 }
168164
})
169165

170-
fastify.route({
171-
method: 'GET',
172-
url: '/hello',
173-
handler: (req, reply) => {
174-
// this will handle http requests
175-
reply.send({ hello: 'world' })
176-
},
177-
wsHandler: (conn, req) => {
178-
// this will handle websockets connections
179-
conn.setEncoding('utf8')
180-
conn.write('hello client')
181-
182-
conn.once('data', chunk => {
183-
conn.end()
184-
})
185-
}
166+
fastify.register(async function () {
167+
fastify.route({
168+
method: 'GET',
169+
url: '/hello',
170+
handler: (req, reply) => {
171+
// this will handle http requests
172+
reply.send({ hello: 'world' })
173+
},
174+
wsHandler: (conn, req) => {
175+
// this will handle websockets connections
176+
conn.setEncoding('utf8')
177+
conn.write('hello client')
178+
179+
conn.once('data', chunk => {
180+
conn.end()
181+
})
182+
}
183+
})
186184
})
187185

188186
fastify.listen(3000, err => {

index.d.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/// <reference types="node" />
22
import { IncomingMessage, ServerResponse, Server } from 'http';
3-
import { FastifyRequest, FastifyPluginCallback, RawServerBase, RawServerDefault, RawRequestDefaultExpression, RawReplyDefaultExpression, RequestGenericInterface, ContextConfigDefault, FastifyInstance } from 'fastify';
3+
import { FastifyRequest, FastifyPluginCallback, RawServerBase, RawServerDefault, RawRequestDefaultExpression, RawReplyDefaultExpression, RequestGenericInterface, ContextConfigDefault, FastifyInstance} from 'fastify';
44
import * as fastify from 'fastify';
55
import * as WebSocket from 'ws';
66
import { Duplex, DuplexOptions } from 'stream';
@@ -18,8 +18,8 @@ declare module 'fastify' {
1818
websocket?: boolean;
1919
}
2020

21-
interface FastifyInstance<RawServer, RawRequest, RawReply> {
22-
get: RouteShorthandMethod<RawServer, RawRequest, RawReply>
21+
interface FastifyInstance<RawServer, RawRequest, RawReply, Logger, TypeProvider> {
22+
get: RouteShorthandMethod<RawServer, RawRequest, RawReply, TypeProvider>,
2323
websocketServer: WebSocket.Server,
2424
}
2525

index.js

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ function fastifyWebsocket (fastify, opts, next) {
8181
})
8282

8383
fastify.addHook('onError', (request, reply, error, done) => {
84+
/* istanbul ignore next */
8485
if (request.raw[kWs]) {
8586
// Hijack reply to prevent fastify from sending the error after onError hooks are done running
8687
reply.hijack()
@@ -92,21 +93,30 @@ function fastifyWebsocket (fastify, opts, next) {
9293
done()
9394
})
9495

96+
fastify.addHook('onResponse', (request, reply, error, done) => {
97+
if (request.ws) {
98+
request.raw[kWs].destroy()
99+
}
100+
done()
101+
})
102+
95103
fastify.addHook('onRoute', routeOptions => {
96104
let isWebsocketRoute = false
97105
let wsHandler = routeOptions.wsHandler
98106
let handler = routeOptions.handler
99107

100108
if (routeOptions.websocket || routeOptions.wsHandler) {
101-
if (routeOptions.method !== 'GET') {
109+
if (routeOptions.method === 'HEAD') {
110+
return
111+
} else if (routeOptions.method !== 'GET') {
102112
throw new Error('websocket handler can only be declared in GET method')
103113
}
104114

105115
isWebsocketRoute = true
106116

107117
if (routeOptions.websocket) {
108118
wsHandler = routeOptions.handler
109-
handler = function (request, reply) {
119+
handler = function (_, reply) {
110120
reply.code(404).send()
111121
}
112122
}
@@ -171,7 +181,7 @@ function fastifyWebsocket (fastify, opts, next) {
171181
connection.socket.close()
172182
}
173183

174-
function defaultErrorHandler (error, conn, request, reply) {
184+
function defaultErrorHandler (error, conn, request) {
175185
// Before destroying the connection, we attach an error listener.
176186
// Since we already handled the error, adding this listener prevents the ws
177187
// library from emitting the error and causing an uncaughtException

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
"homepage": "https://github.com/fastify/fastify-websocket#readme",
3131
"devDependencies": {
3232
"@types/ws": "^8.2.2",
33-
"fastify": "^3.25.3",
33+
"fastify": "^4.0.0-rc.2",
3434
"pre-commit": "^1.2.2",
3535
"snazzy": "^9.0.0",
3636
"split2": "^4.1.0",

0 commit comments

Comments
 (0)