@fastify/websocket
Advanced tools
Comparing version 9.0.0 to 10.0.0
36
index.js
@@ -125,16 +125,7 @@ 'use strict' | ||
const connection = WebSocket.createWebSocketStream(socket, opts.connectionOptions) | ||
connection.socket = socket | ||
connection.on('error', (error) => { | ||
socket.on('error', (error) => { | ||
fastify.log.error(error) | ||
}) | ||
connection.socket.on('newListener', event => { | ||
if (event === 'message') { | ||
connection.resume() | ||
} | ||
}) | ||
callback(connection) | ||
callback(socket) | ||
}) | ||
@@ -191,16 +182,16 @@ } | ||
reply.hijack() | ||
handleUpgrade(request.raw, connection => { | ||
handleUpgrade(request.raw, socket => { | ||
let result | ||
try { | ||
if (isWebsocketRoute) { | ||
result = wsHandler.call(this, connection, request) | ||
result = wsHandler.call(this, socket, request) | ||
} else { | ||
result = noHandle.call(this, connection, request) | ||
result = noHandle.call(this, socket, request) | ||
} | ||
} catch (err) { | ||
return errorHandler.call(this, err, connection, request, reply) | ||
return errorHandler.call(this, err, socket, request, reply) | ||
} | ||
if (result && typeof result.catch === 'function') { | ||
result.catch(err => errorHandler.call(this, err, connection, request, reply)) | ||
result.catch(err => errorHandler.call(this, err, socket, request, reply)) | ||
} | ||
@@ -234,15 +225,10 @@ }) | ||
function noHandle (connection, rawRequest) { | ||
function noHandle (socket, rawRequest) { | ||
this.log.info({ path: rawRequest.url }, 'closed incoming websocket connection for path with no websocket handler') | ||
connection.socket.close() | ||
socket.close() | ||
} | ||
function defaultErrorHandler (error, conn, request) { | ||
// Before destroying the connection, we attach an error listener. | ||
// Since we already handled the error, adding this listener prevents the ws | ||
// library from emitting the error and causing an uncaughtException | ||
// Reference: https://github.com/websockets/ws/blob/master/lib/stream.js#L35 | ||
conn.on('error', _ => { }) | ||
function defaultErrorHandler (error, socket, request) { | ||
request.log.error(error) | ||
conn.destroy(error) | ||
socket.terminate() | ||
} | ||
@@ -249,0 +235,0 @@ |
{ | ||
"name": "@fastify/websocket", | ||
"version": "9.0.0", | ||
"version": "10.0.0", | ||
"description": "basic websocket support for fastify", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
100
README.md
@@ -36,6 +36,6 @@ # @fastify/websocket | ||
fastify.register(async function (fastify) { | ||
fastify.get('/', { websocket: true }, (connection /* SocketStream */, req /* FastifyRequest */) => { | ||
connection.socket.on('message', message => { | ||
fastify.get('/', { websocket: true }, (socket /* WebSocket */, req /* FastifyRequest */) => { | ||
socket.on('message', message => { | ||
// message.toString() === 'hi from client' | ||
connection.socket.send('hi from server') | ||
socket.send('hi from server') | ||
}) | ||
@@ -67,13 +67,13 @@ }) | ||
fastify.register(async function (fastify) { | ||
fastify.get('/*', { websocket: true }, (connection /* SocketStream */, req /* FastifyRequest */) => { | ||
connection.socket.on('message', message => { | ||
fastify.get('/*', { websocket: true }, (socket /* WebSocket */, req /* FastifyRequest */) => { | ||
socket.on('message', message => { | ||
// message.toString() === 'hi from client' | ||
connection.socket.send('hi from wildcard route') | ||
socket.send('hi from wildcard route') | ||
}) | ||
}) | ||
fastify.get('/', { websocket: true }, (connection /* SocketStream */, req /* FastifyRequest */) => { | ||
connection.socket.on('message', message => { | ||
fastify.get('/', { websocket: true }, (socket /* WebSocket */, req /* FastifyRequest */) => { | ||
socket.on('message', message => { | ||
// message.toString() === 'hi from client' | ||
connection.socket.send('hi from server') | ||
socket.send('hi from server') | ||
}) | ||
@@ -98,6 +98,6 @@ }) | ||
```javascript | ||
fastify.get('/*', { websocket: true }, (connection, request) => { | ||
fastify.get('/*', { websocket: true }, (socket, request) => { | ||
const sessionPromise = request.getSession() // example async session getter, called synchronously to return a promise | ||
connection.socket.on('message', async (message) => { | ||
socket.on('message', async (message) => { | ||
const session = await sessionPromise() | ||
@@ -119,5 +119,5 @@ // do something with the message and session | ||
}) | ||
fastify.get('/', { websocket: true }, (connection, req) => { | ||
fastify.get('/', { websocket: true }, (socket, req) => { | ||
// the connection will only be opened for authenticated incoming requests | ||
connection.socket.on('message', message => { | ||
socket.on('message', message => { | ||
// ... | ||
@@ -141,9 +141,9 @@ }) | ||
fastify.get('/', { websocket: true }, function wsHandler (connection, req) { | ||
fastify.get('/', { websocket: true }, function wsHandler (socket, req) { | ||
// bound to fastify server | ||
this.myDecoration.someFunc() | ||
connection.socket.on('message', message => { | ||
socket.on('message', message => { | ||
// message.toString() === 'hi from client' | ||
connection.socket.send('hi from server') | ||
socket.send('hi from server') | ||
}) | ||
@@ -162,4 +162,4 @@ }) | ||
function handle (conn, req) { | ||
conn.pipe(conn) // creates an echo server | ||
function handle (socket, req) { | ||
socket.on('message', (data) => socket.send(data)) // creates an echo server | ||
} | ||
@@ -180,9 +180,8 @@ | ||
}, | ||
wsHandler: (conn, req) => { | ||
wsHandler: (socket, req) => { | ||
// this will handle websockets connections | ||
conn.setEncoding('utf8') | ||
conn.write('hello client') | ||
socket.send('hello client') | ||
conn.once('data', chunk => { | ||
conn.end() | ||
socket.once('message', chunk => { | ||
socket.close() | ||
}) | ||
@@ -211,6 +210,6 @@ } | ||
fastify.register(require('@fastify/websocket'), { | ||
errorHandler: function (error, conn /* SocketStream */, req /* FastifyRequest */, reply /* FastifyReply */) { | ||
errorHandler: function (error, socket /* WebSocket */, req /* FastifyRequest */, reply /* FastifyReply */) { | ||
// Do stuff | ||
// destroy/close connection | ||
conn.destroy(error) | ||
socket.terminate() | ||
}, | ||
@@ -228,6 +227,6 @@ options: { | ||
fastify.get('/', { websocket: true }, (connection /* SocketStream */, req /* FastifyRequest */) => { | ||
connection.socket.on('message', message => { | ||
fastify.get('/', { websocket: true }, (socket /* WebSocket */, req /* FastifyRequest */) => { | ||
socket.on('message', message => { | ||
// message.toString() === 'hi from client' | ||
connection.socket.send('hi from server') | ||
socket.send('hi from server') | ||
}) | ||
@@ -259,4 +258,4 @@ }) | ||
for (const connection of server.clients) { | ||
connection.close(1001, 'WS server is going offline in custom manner, sending a code + message') | ||
for (const socket of server.clients) { | ||
socket.close(1001, 'WS server is going offline in custom manner, sending a code + message') | ||
} | ||
@@ -276,2 +275,28 @@ | ||
### Creating a stream from the WebSocket | ||
```js | ||
const Fastify = require('fastify') | ||
const FastifyWebSocket = require('@fastify/websocket') | ||
const ws = require('ws') | ||
const fastify = Fastify() | ||
await fastify.register(websocket) | ||
fastify.get('/', { websocket: true }, (socket, req) => { | ||
const stream = ws.createWebSocketStream(socket, { /* options */ }) | ||
stream.setEncoding('utf8') | ||
stream.write('hello client') | ||
stream.on('data', function (data) { | ||
// Make sure to set up a data handler or read all the incoming | ||
// data in another way, otherwise stream backpressure will cause | ||
// the underlying WebSocket object to get paused. | ||
}) | ||
}) | ||
await fastify.listen({ port: 3000 }) | ||
``` | ||
#### App.js | ||
@@ -296,5 +321,5 @@ | ||
fastify.get('/', { websocket: true }, (connection) => { | ||
connection.socket.on('message', message => { | ||
connection.socket.send('hi from server') | ||
fastify.get('/', { websocket: true }, (socket) => { | ||
socket.on('message', message => { | ||
socket.send('hi from server') | ||
}) | ||
@@ -365,11 +390,2 @@ }) | ||
You can also pass the following as `connectionOptions` for [createWebSocketStream](https://github.com/websockets/ws/blob/master/doc/ws.md#createwebsocketstreamwebsocket-options). | ||
- `allowHalfOpen` <boolean> If set to false, then the stream will automatically end the writable side when the readable side ends. Default: true. | ||
- `readable` <boolean> Sets whether the Duplex should be readable. Default: true. | ||
- `writable` <boolean> Sets whether the Duplex should be writable. Default: true. | ||
- `readableObjectMode` <boolean> Sets objectMode for readable side of the stream. Has no effect if objectMode is true. Default: false. | ||
- `readableHighWaterMark` <number> Sets highWaterMark for the readable side of the stream. | ||
- `writableHighWaterMark` <number> Sets highWaterMark for the writable side of the stream. | ||
[ws](https://github.com/websockets/ws) does not allow you to set `objectMode` or `writableObjectMode` to true | ||
@@ -376,0 +392,0 @@ ## Acknowledgements |
'use strict' | ||
const http = require('node:http') | ||
const util = require('node:util') | ||
const split = require('split2') | ||
@@ -25,10 +24,8 @@ const test = require('tap').test | ||
fastify.get('/', { websocket: true }, (connection) => { | ||
connection.setEncoding('utf8') | ||
t.teardown(() => connection.destroy()) | ||
fastify.get('/', { websocket: true }, (socket) => { | ||
t.teardown(() => socket.terminate()) | ||
connection.once('data', (chunk) => { | ||
t.equal(chunk, 'hello server') | ||
connection.write('hello client') | ||
connection.end() | ||
socket.once('message', (chunk) => { | ||
t.equal(chunk.toString(), 'hello server') | ||
socket.send('hello client') | ||
}) | ||
@@ -40,11 +37,11 @@ }) | ||
const ws = new WebSocket('ws://localhost:' + fastify.server.address().port) | ||
const client = WebSocket.createWebSocketStream(ws, { encoding: 'utf8' }) | ||
t.teardown(() => client.destroy()) | ||
t.teardown(() => ws.close()) | ||
client.setEncoding('utf8') | ||
client.write('hello server') | ||
const chunkPromise = once(ws, 'message') | ||
await once(ws, 'open') | ||
ws.send('hello server') | ||
const [chunk] = await once(client, 'data') | ||
t.equal(chunk, 'hello client') | ||
client.end() | ||
const [chunk] = await chunkPromise | ||
t.equal(chunk.toString(), 'hello client') | ||
ws.close() | ||
}) | ||
@@ -64,4 +61,4 @@ | ||
fastify.get('/', { websocket: true }, (connection) => { | ||
t.teardown(() => connection.destroy()) | ||
fastify.get('/', { websocket: true }, (socket) => { | ||
t.teardown(() => socket.terminate()) | ||
}) | ||
@@ -94,5 +91,5 @@ | ||
fastify.get('/*', { websocket: true }, (conn) => { | ||
conn.pipe(conn) | ||
t.teardown(() => conn.destroy()) | ||
fastify.get('/*', { websocket: true }, (socket) => { | ||
socket.on('message', (data) => socket.send(data)) | ||
t.teardown(() => socket.terminate()) | ||
return Promise.reject(new Error('Fail')) | ||
@@ -104,4 +101,4 @@ }) | ||
const ws = new WebSocket('ws://localhost:' + fastify.server.address().port) | ||
const client = WebSocket.createWebSocketStream(ws, { encoding: 'utf8' }) | ||
t.teardown(() => client.destroy()) | ||
t.teardown(() => ws.close()) | ||
await p | ||
@@ -128,5 +125,5 @@ }) | ||
fastify.get('/', { websocket: true }, function wsHandler (conn) { | ||
conn.pipe(conn) | ||
t.teardown(() => conn.destroy()) | ||
fastify.get('/', { websocket: true }, function wsHandler (socket) { | ||
socket.on('message', (data) => socket.send(data)) | ||
t.teardown(() => socket.terminate()) | ||
throw new Error('Fail') | ||
@@ -137,4 +134,3 @@ }) | ||
const ws = new WebSocket('ws://localhost:' + fastify.server.address().port) | ||
const client = WebSocket.createWebSocketStream(ws, { encoding: 'utf8' }) | ||
t.teardown(() => client.destroy()) | ||
t.teardown(() => ws.close()) | ||
@@ -162,5 +158,5 @@ await p | ||
fastify.get('/', { websocket: true }, async function wsHandler (conn) { | ||
conn.pipe(conn) | ||
t.teardown(() => conn.destroy()) | ||
fastify.get('/', { websocket: true }, async function wsHandler (socket) { | ||
socket.on('message', (data) => socket.send(data)) | ||
t.teardown(() => socket.terminate()) | ||
throw new Error('Fail') | ||
@@ -171,8 +167,8 @@ }) | ||
const ws = new WebSocket('ws://localhost:' + fastify.server.address().port) | ||
const client = WebSocket.createWebSocketStream(ws, { encoding: 'utf8' }) | ||
t.teardown(() => client.destroy()) | ||
t.teardown(() => ws.close()) | ||
await p | ||
}) | ||
test('Should be able to pass custom options to websocket-stream', async (t) => { | ||
test('Should be able to pass custom options to ws', async (t) => { | ||
t.plan(2) | ||
@@ -193,5 +189,5 @@ | ||
fastify.get('/*', { websocket: true }, (connection) => { | ||
connection.pipe(connection) | ||
t.teardown(() => connection.destroy()) | ||
fastify.get('/*', { websocket: true }, (socket) => { | ||
socket.on('message', (data) => socket.send(data)) | ||
t.teardown(() => socket.terminate()) | ||
}) | ||
@@ -203,14 +199,14 @@ | ||
const ws = new WebSocket('ws://localhost:' + fastify.server.address().port, clientOptions) | ||
const client = WebSocket.createWebSocketStream(ws, { encoding: 'utf8' }) | ||
t.teardown(() => client.destroy()) | ||
const chunkPromise = once(ws, 'message') | ||
await once(ws, 'open') | ||
t.teardown(() => ws.close()) | ||
client.setEncoding('utf8') | ||
client.write('hello') | ||
ws.send('hello') | ||
const [chunk] = await once(client, 'data') | ||
t.equal(chunk, 'hello') | ||
client.end() | ||
const [chunk] = await chunkPromise | ||
t.equal(chunk.toString(), 'hello') | ||
ws.close() | ||
}) | ||
test('Should warn if path option is provided to websocket-stream', async (t) => { | ||
test('Should warn if path option is provided to ws', async (t) => { | ||
t.plan(3) | ||
@@ -235,5 +231,5 @@ const logStream = split(JSON.parse) | ||
fastify.get('/*', { websocket: true }, (connection) => { | ||
connection.pipe(connection) | ||
t.teardown(() => connection.destroy()) | ||
fastify.get('/*', { websocket: true }, (socket) => { | ||
socket.on('message', (data) => socket.send(data)) | ||
t.teardown(() => socket.terminate()) | ||
}) | ||
@@ -245,14 +241,14 @@ | ||
const ws = new WebSocket('ws://localhost:' + fastify.server.address().port, clientOptions) | ||
const client = WebSocket.createWebSocketStream(ws, { encoding: 'utf8' }) | ||
t.teardown(() => client.destroy()) | ||
const chunkPromise = once(ws, 'message') | ||
await once(ws, 'open') | ||
t.teardown(() => ws.close()) | ||
client.setEncoding('utf8') | ||
client.write('hello') | ||
ws.send('hello') | ||
const [chunk] = await once(client, 'data') | ||
t.equal(chunk, 'hello') | ||
client.end() | ||
const [chunk] = await chunkPromise | ||
t.equal(chunk.toString(), 'hello') | ||
ws.close() | ||
}) | ||
test('Should be able to pass a custom server option to websocket-stream', async (t) => { | ||
test('Should be able to pass a custom server option to ws', async (t) => { | ||
// We create an external server | ||
@@ -279,5 +275,5 @@ const externalServerPort = 3000 | ||
fastify.get('/', { websocket: true }, (connection) => { | ||
connection.pipe(connection) | ||
t.teardown(() => connection.destroy()) | ||
fastify.get('/', { websocket: true }, (socket) => { | ||
socket.on('message', (data) => socket.send(data)) | ||
t.teardown(() => socket.terminate()) | ||
}) | ||
@@ -288,14 +284,14 @@ | ||
const ws = new WebSocket('ws://localhost:' + externalServerPort) | ||
const client = WebSocket.createWebSocketStream(ws, { encoding: 'utf8' }) | ||
t.teardown(() => client.destroy()) | ||
const chunkPromise = once(ws, 'message') | ||
await once(ws, 'open') | ||
t.teardown(() => ws.close()) | ||
client.setEncoding('utf8') | ||
client.write('hello') | ||
ws.send('hello') | ||
const [chunk] = await once(client, 'data') | ||
t.equal(chunk, 'hello') | ||
client.end() | ||
const [chunk] = await chunkPromise | ||
t.equal(chunk.toString(), 'hello') | ||
ws.close() | ||
}) | ||
test('Should be able to pass clientTracking option in false to websocket-stream', (t) => { | ||
test('Should be able to pass clientTracking option in false to ws', (t) => { | ||
t.plan(2) | ||
@@ -311,4 +307,4 @@ | ||
fastify.get('/*', { websocket: true }, (connection) => { | ||
connection.destroy() | ||
fastify.get('/*', { websocket: true }, (socket) => { | ||
socket.close() | ||
}) | ||
@@ -325,42 +321,2 @@ | ||
test('Should be able to pass custom connectionOptions to createWebSocketStream', async (t) => { | ||
t.plan(2) | ||
const fastify = Fastify() | ||
t.teardown(() => fastify.close()) | ||
const connectionOptions = { | ||
readableObjectMode: true | ||
} | ||
await fastify.register(fastifyWebsocket, { connectionOptions }) | ||
let _resolve | ||
const p = new Promise((resolve) => { | ||
_resolve = resolve | ||
}) | ||
fastify.get('/', { websocket: true }, (connection) => { | ||
t.equal(connection.readableObjectMode, true) | ||
connection.socket.binaryType = 'arraybuffer' | ||
connection.once('data', (chunk) => { | ||
const message = new util.TextDecoder().decode(chunk) | ||
t.equal(message, 'Hello') | ||
_resolve() | ||
}) | ||
t.teardown(() => connection.destroy()) | ||
}) | ||
await fastify.listen({ port: 0 }) | ||
const ws = new WebSocket('ws://localhost:' + fastify.server.address().port) | ||
const client = WebSocket.createWebSocketStream(ws, { encoding: 'utf8' }) | ||
t.teardown(() => client.destroy()) | ||
client.setEncoding('utf8') | ||
client.write('Hello') | ||
await p | ||
}) | ||
test('Should be able to pass preClose option to override default', async (t) => { | ||
@@ -382,10 +338,8 @@ t.plan(3) | ||
fastify.get('/', { websocket: true }, (connection) => { | ||
connection.setEncoding('utf8') | ||
t.teardown(() => connection.destroy()) | ||
fastify.get('/', { websocket: true }, (socket) => { | ||
t.teardown(() => socket.terminate()) | ||
connection.once('data', (chunk) => { | ||
t.equal(chunk, 'hello server') | ||
connection.write('hello client') | ||
connection.end() | ||
socket.once('message', (chunk) => { | ||
t.equal(chunk.toString(), 'hello server') | ||
socket.send('hello client') | ||
}) | ||
@@ -397,11 +351,11 @@ }) | ||
const ws = new WebSocket('ws://localhost:' + fastify.server.address().port) | ||
const client = WebSocket.createWebSocketStream(ws, { encoding: 'utf8' }) | ||
t.teardown(() => client.destroy()) | ||
t.teardown(() => ws.close()) | ||
client.setEncoding('utf8') | ||
client.write('hello server') | ||
const chunkPromise = once(ws, 'message') | ||
await once(ws, 'open') | ||
ws.send('hello server') | ||
const [chunk] = await once(client, 'data') | ||
t.equal(chunk, 'hello client') | ||
client.end() | ||
const [chunk] = await chunkPromise | ||
t.equal(chunk.toString(), 'hello client') | ||
ws.close() | ||
@@ -425,4 +379,4 @@ await fastify.close() | ||
fastify.get('/', { websocket: true }, (connection) => { | ||
t.teardown(() => connection.destroy()) | ||
fastify.get('/', { websocket: true }, (socket) => { | ||
t.teardown(() => socket.terminate()) | ||
}) | ||
@@ -445,11 +399,10 @@ | ||
fastify.get('/', { websocket: true }, (connection) => { | ||
connection.setEncoding('utf8') | ||
connection.write('hello client') | ||
fastify.get('/', { websocket: true }, (socket) => { | ||
socket.send('hello client') | ||
connection.once('data', (chunk) => { | ||
t.equal(chunk, 'hello server') | ||
socket.once('message', (chunk) => { | ||
t.equal(chunk.toString(), 'hello server') | ||
}) | ||
serverConnEnded = once(connection, 'end') | ||
serverConnEnded = once(socket, 'close') | ||
// this connection stays alive untile we close the server | ||
@@ -461,11 +414,9 @@ }) | ||
const ws = new WebSocket('ws://localhost:' + fastify.server.address().port) | ||
const client = WebSocket.createWebSocketStream(ws, { encoding: 'utf8' }) | ||
const chunkPromise = once(ws, 'message') | ||
await once(ws, 'open') | ||
ws.send('hello server') | ||
client.setEncoding('utf8') | ||
client.write('hello server') | ||
const ended = once(client, 'end') | ||
const [chunk] = await once(client, 'data') | ||
t.equal(chunk, 'hello client') | ||
const ended = once(ws, 'close') | ||
const [chunk] = await chunkPromise | ||
t.equal(chunk.toString(), 'hello client') | ||
await fastify.close() | ||
@@ -494,5 +445,5 @@ await ended | ||
fastify.get('/', { websocket: true }, (connection) => { | ||
fastify.get('/', { websocket: true }, (socket) => { | ||
t.pass('received client connection') | ||
connection.destroy() | ||
socket.close() | ||
// this connection stays alive until we close the server | ||
@@ -531,3 +482,3 @@ }) | ||
fastify.get('/', { websocket: true }, ({ socket }) => { | ||
fastify.get('/', { websocket: true }, (socket) => { | ||
socket.on('message', () => { | ||
@@ -588,3 +539,3 @@ unhandled-- | ||
fastify.get('/', { websocket: true }, ({ socket }) => { | ||
fastify.get('/', { websocket: true }, (socket) => { | ||
socket.on('message', () => { | ||
@@ -659,3 +610,3 @@ socket.send('handled') | ||
fastify.get('/', { websocket: true }, ({ socket }) => { | ||
fastify.get('/', { websocket: true }, (socket) => { | ||
socket.on('error', err => { | ||
@@ -662,0 +613,0 @@ t.equal(err.code, 'WS_ERR_UNEXPECTED_RSV_2_3') |
@@ -24,10 +24,8 @@ 'use strict' | ||
fastify.get('/echo', { websocket: true }, (conn, request) => { | ||
conn.setEncoding('utf8') | ||
conn.write('hello client') | ||
t.teardown(conn.destroy.bind(conn)) | ||
fastify.get('/echo', { websocket: true }, (socket, request) => { | ||
socket.send('hello client') | ||
t.teardown(() => socket.terminate()) | ||
conn.once('data', chunk => { | ||
t.equal(chunk, 'hello server') | ||
conn.end() | ||
socket.once('message', (chunk) => { | ||
t.equal(chunk.toString(), 'hello server') | ||
}) | ||
@@ -64,7 +62,6 @@ }) | ||
fastify.get('/echo', { websocket: true }, (conn, request) => { | ||
conn.setEncoding('utf8') | ||
conn.write('hello client') | ||
fastify.get('/echo', { websocket: true }, (socket, request) => { | ||
socket.send('hello client') | ||
request.raw.setTimeout(50) | ||
t.teardown(conn.destroy.bind(conn)) | ||
t.teardown(() => socket.terminate()) | ||
}) | ||
@@ -211,4 +208,4 @@ }) | ||
fastify.get('/echo', { websocket: true }, async (conn, request) => { | ||
t.teardown(conn.destroy.bind(conn)) | ||
fastify.get('/echo', { websocket: true }, async (socket, request) => { | ||
t.teardown(() => socket.terminate()) | ||
throw new Error('Fail') | ||
@@ -239,7 +236,5 @@ }) | ||
fastify.get('/echo', { websocket: true }, async (conn, request) => { | ||
conn.setEncoding('utf8') | ||
conn.write('hello client') | ||
t.teardown(conn.destroy.bind(conn)) | ||
conn.end() | ||
fastify.get('/echo', { websocket: true }, async (socket, request) => { | ||
socket.send('hello client') | ||
t.teardown(() => socket.terminate()) | ||
}) | ||
@@ -306,10 +301,8 @@ }) | ||
fastify.get('/echo', { websocket: true }, (conn, request) => { | ||
conn.setEncoding('utf8') | ||
conn.write('hello client') | ||
t.teardown(conn.destroy.bind(conn)) | ||
fastify.get('/echo', { websocket: true }, (socket, request) => { | ||
socket.send('hello client') | ||
t.teardown(() => socket.terminate()) | ||
conn.socket.on('message', (message) => { | ||
socket.on('message', (message) => { | ||
t.equal(message.toString('utf-8'), 'hello server') | ||
conn.end() | ||
}) | ||
@@ -370,3 +363,3 @@ }) | ||
test('Should not hijack reply for an WS request to a WS route that gets sent a normal HTTP response in a hook', t => { | ||
t.plan(6) | ||
t.plan(2) | ||
const stream = split(JSON.parse) | ||
@@ -386,3 +379,5 @@ const fastify = Fastify({ logger: { stream } }) | ||
stream.on('data', (chunk) => { | ||
t.ok(chunk.level < 50) | ||
if (chunk.level >= 50) { | ||
t.fail() | ||
} | ||
}) | ||
@@ -389,0 +384,0 @@ |
@@ -23,4 +23,4 @@ 'use strict' | ||
async function (instance) { | ||
instance.get('/ws', { websocket: true }, function (conn) { | ||
conn.once('data', chunk => { | ||
instance.get('/ws', { websocket: true }, function (socket) { | ||
socket.once('message', chunk => { | ||
_resolve(chunk.toString()) | ||
@@ -47,4 +47,4 @@ }) | ||
async function (instance) { | ||
instance.get('/', { websocket: true }, function (conn) { | ||
conn.once('data', chunk => { | ||
instance.get('/', { websocket: true }, function (socket) { | ||
socket.once('message', chunk => { | ||
_resolve(chunk.toString()) | ||
@@ -72,4 +72,4 @@ }) | ||
async function (instance) { | ||
instance.get('/ws', { websocket: true }, function (conn) { | ||
conn.once('data', () => { | ||
instance.get('/ws', { websocket: true }, function (socket) { | ||
socket.once('message', chunk => { | ||
_reject('wrong-route') | ||
@@ -79,4 +79,4 @@ }) | ||
instance.get('/ws-2', { websocket: true }, function (conn) { | ||
conn.once('data', chunk => { | ||
instance.get('/ws-2', { websocket: true }, function (socket) { | ||
socket.once('message', chunk => { | ||
_resolve(chunk.toString()) | ||
@@ -109,4 +109,4 @@ }) | ||
instance.get('/', { websocket: true }, function (conn) { | ||
conn.once('data', chunk => { | ||
instance.get('/', { websocket: true }, function (socket) { | ||
socket.once('message', chunk => { | ||
_resolve(chunk.toString()) | ||
@@ -113,0 +113,0 @@ }) |
@@ -19,11 +19,9 @@ 'use strict' | ||
function (instance, opts, next) { | ||
instance.get('/echo', { websocket: true }, function (conn, request) { | ||
instance.get('/echo', { websocket: true }, function (socket, request) { | ||
t.equal(this.prefix, '/baz') | ||
conn.setEncoding('utf8') | ||
conn.write('hello client') | ||
t.teardown(conn.destroy.bind(conn)) | ||
socket.send('hello client') | ||
t.teardown(() => socket.terminate()) | ||
conn.once('data', chunk => { | ||
t.equal(chunk, 'hello server') | ||
conn.end() | ||
socket.once('message', (chunk) => { | ||
t.equal(chunk.toString(), 'hello server') | ||
}) | ||
@@ -61,10 +59,8 @@ }) | ||
function (instance, opts, next) { | ||
instance.get('/', { websocket: true }, (conn, req) => { | ||
conn.setEncoding('utf8') | ||
conn.write('hello client') | ||
t.teardown(conn.destroy.bind(conn)) | ||
instance.get('/', { websocket: true }, (socket, req) => { | ||
socket.send('hello client') | ||
t.teardown(() => socket.terminate()) | ||
conn.once('data', chunk => { | ||
t.equal(chunk, 'hello server') | ||
conn.end() | ||
socket.once('message', (chunk) => { | ||
t.equal(chunk.toString(), 'hello server') | ||
}) | ||
@@ -108,10 +104,8 @@ }) | ||
}, | ||
wsHandler: (conn, req) => { | ||
conn.setEncoding('utf8') | ||
conn.write('hello client') | ||
t.teardown(conn.destroy.bind(conn)) | ||
wsHandler: (socket, req) => { | ||
socket.send('hello client') | ||
t.teardown(() => socket.terminate()) | ||
conn.once('data', chunk => { | ||
t.equal(chunk, 'hello server') | ||
conn.end() | ||
socket.once('message', (chunk) => { | ||
t.equal(chunk.toString(), 'hello server') | ||
}) | ||
@@ -168,12 +162,12 @@ } | ||
fastify.get('/echo', { websocket: true }, (connection, request) => { | ||
connection.socket.on('message', message => { | ||
fastify.get('/echo', { websocket: true }, (socket, request) => { | ||
socket.on('message', message => { | ||
try { | ||
connection.socket.send(message) | ||
socket.send(message) | ||
} catch (err) { | ||
connection.socket.send(err.message) | ||
socket.send(err.message) | ||
} | ||
}) | ||
t.teardown(connection.destroy.bind(connection)) | ||
t.teardown(() => socket.terminate()) | ||
}) | ||
@@ -208,8 +202,8 @@ }) | ||
}, | ||
wsHandler: (conn) => { | ||
conn.setEncoding('utf8') | ||
conn.write('hello client') | ||
wsHandler: (socket) => { | ||
socket.send('hello client') | ||
t.teardown(() => socket.terminate()) | ||
conn.once('data', () => { | ||
conn.end() | ||
socket.once('message', (chunk) => { | ||
socket.close() | ||
}) | ||
@@ -242,24 +236,24 @@ } | ||
.register(async function (fastify) { | ||
fastify.get('/*', { websocket: true }, (conn) => { | ||
conn.socket.on('message', () => { | ||
fastify.get('/*', { websocket: true }, (socket) => { | ||
socket.on('message', () => { | ||
try { | ||
conn.socket.send('hi from wildcard route handler') | ||
socket.send('hi from wildcard route handler') | ||
} catch (err) { | ||
conn.socket.send(err.message) | ||
socket.send(err.message) | ||
} | ||
}) | ||
t.teardown(conn.destroy.bind(conn)) | ||
t.teardown(() => socket.terminate()) | ||
}) | ||
}) | ||
fastify.get('/echo', { websocket: true }, (conn) => { | ||
conn.socket.on('message', () => { | ||
fastify.get('/echo', { websocket: true }, (socket) => { | ||
socket.on('message', () => { | ||
try { | ||
conn.socket.send('hi from /echo handler') | ||
socket.send('hi from /echo handler') | ||
} catch (err) { | ||
conn.socket.send(err.message) | ||
socket.send(err.message) | ||
} | ||
}) | ||
t.teardown(conn.destroy.bind(conn)) | ||
t.teardown(() => socket.terminate()) | ||
}) | ||
@@ -302,5 +296,5 @@ | ||
}, | ||
wsHandler: (conn, request) => { | ||
conn.write('hi from wsHandler') | ||
t.teardown(conn.destroy.bind(conn)) | ||
wsHandler: (socket, request) => { | ||
socket.send('hi from wsHandler') | ||
t.teardown(() => socket.terminate()) | ||
} | ||
@@ -340,6 +334,6 @@ }) | ||
fastify.register(async function (fastify) { | ||
fastify.get('/*', { websocket: true }, (conn, request) => { | ||
fastify.get('/*', { websocket: true }, (socket, request) => { | ||
t.ok('called', 'wildcard handler') | ||
conn.end() | ||
t.teardown(conn.destroy.bind(conn)) | ||
socket.close() | ||
t.teardown(() => socket.terminate()) | ||
}) | ||
@@ -371,5 +365,5 @@ | ||
fastify.register(async function (fastify) { | ||
fastify.get('/*', { websocket: true }, (conn, request) => { | ||
fastify.get('/*', { websocket: true }, (socket, request) => { | ||
t.fail('called', 'wildcard handler') | ||
t.teardown(conn.destroy.bind(conn)) | ||
t.teardown(() => socket.terminate()) | ||
}) | ||
@@ -401,11 +395,11 @@ | ||
fastify.register(async function (fastify) { | ||
fastify.post('/echo', { websocket: true }, (connection, request) => { | ||
connection.socket.on('message', message => { | ||
fastify.post('/echo', { websocket: true }, (socket, request) => { | ||
socket.on('message', message => { | ||
try { | ||
connection.socket.send(message) | ||
socket.send(message) | ||
} catch (err) { | ||
connection.socket.send(err.message) | ||
socket.send(err.message) | ||
} | ||
}) | ||
t.teardown(connection.destroy.bind(connection)) | ||
t.teardown(() => socket.terminate()) | ||
}) | ||
@@ -455,12 +449,12 @@ | ||
fastify.register(async function (fastify) { | ||
fastify.get('/echo', { websocket: true }, (connection, request) => { | ||
connection.socket.on('message', message => { | ||
fastify.get('/echo', { websocket: true }, (socket, request) => { | ||
socket.on('message', message => { | ||
try { | ||
connection.socket.send(message) | ||
socket.send(message) | ||
} catch (err) { | ||
connection.socket.send(err.message) | ||
socket.send(err.message) | ||
} | ||
}) | ||
t.teardown(connection.destroy.bind(connection)) | ||
t.teardown(() => socket.terminate()) | ||
}) | ||
@@ -491,13 +485,13 @@ }) | ||
fastify.register(async function (fastify) { | ||
fastify.get('/', { websocket: true }, (connection, request) => { | ||
connection.socket.on('message', message => { | ||
fastify.get('/', { websocket: true }, (socket, request) => { | ||
socket.on('message', message => { | ||
t.equal(message.toString(), 'hi from client') | ||
connection.socket.send('hi from server') | ||
socket.send('hi from server') | ||
}) | ||
connection.socket.on('close', () => { | ||
socket.on('close', () => { | ||
t.pass() | ||
}) | ||
t.teardown(connection.destroy.bind(connection)) | ||
t.teardown(() => socket.terminate()) | ||
}) | ||
@@ -534,13 +528,13 @@ }) | ||
fastify.register(async function (fastify) { | ||
fastify.get('/', { websocket: true }, (connection, request) => { | ||
connection.socket.on('message', message => { | ||
fastify.get('/', { websocket: true }, (socket, request) => { | ||
socket.on('message', message => { | ||
t.equal(message.toString(), 'hi from client') | ||
connection.socket.send('hi from server') | ||
socket.send('hi from server') | ||
}) | ||
connection.socket.on('close', () => { | ||
socket.on('close', () => { | ||
t.pass() | ||
}) | ||
t.teardown(connection.destroy.bind(connection)) | ||
t.teardown(() => socket.terminate()) | ||
}) | ||
@@ -566,13 +560,13 @@ }) | ||
fastify.register(async function (fastify) { | ||
fastify.get('/ws', { websocket: true }, (conn, request) => { | ||
fastify.get('/ws', { websocket: true }, (socket, request) => { | ||
const params = request.params | ||
t.equal(Object.keys(params).length, 0, 'params are empty') | ||
conn.write('empty') | ||
conn.end() | ||
socket.send('empty') | ||
socket.close() | ||
}) | ||
fastify.get('/ws/:id', { websocket: true }, (conn, request) => { | ||
fastify.get('/ws/:id', { websocket: true }, (socket, request) => { | ||
const params = request.params | ||
t.equal(params.id, 'foo', 'params are correct') | ||
conn.write(params.id) | ||
conn.end() | ||
socket.send(params.id) | ||
socket.close() | ||
}) | ||
@@ -620,6 +614,6 @@ }) | ||
function (instance, opts, next) { | ||
instance.get('/', { websocket: true }, (connection, request) => { | ||
connection.socket.on('message', message => { | ||
instance.get('/', { websocket: true }, (socket, request) => { | ||
socket.on('message', message => { | ||
t.equal(message.toString(), 'hi from client') | ||
connection.socket.send('hi from server') | ||
socket.send('hi from server') | ||
}) | ||
@@ -654,6 +648,6 @@ }) | ||
fastify.register(async function (fastify) { | ||
fastify.get('/ws', { websocket: true }, function wsHandler (conn) { | ||
fastify.get('/ws', { websocket: true }, function wsHandler (socket) { | ||
t.equal(this, fastify, 'this is bound to fastify server') | ||
conn.write('empty') | ||
conn.end() | ||
socket.send('empty') | ||
socket.close() | ||
}) | ||
@@ -688,6 +682,6 @@ }) | ||
fastify.register(async function (fastify) { | ||
fastify.get('/ws', { websocket: true }, function wsHandler (conn, request) { | ||
fastify.get('/ws', { websocket: true }, function wsHandler (socket, request) { | ||
t.equal(request.str, 'it works!', 'decorator is accessible') | ||
conn.write('empty') | ||
conn.end() | ||
socket.send('empty') | ||
socket.close() | ||
}) | ||
@@ -718,5 +712,5 @@ }) | ||
fastify.register(async function (fastify) { | ||
fastify.get('/ws', { websocket: true }, async function wsHandler (conn, request) { | ||
conn.on('error', err => { | ||
t.equal(err.message, 'something wrong') | ||
fastify.get('/ws', { websocket: true }, async function wsHandler (socket, request) { | ||
socket.on('close', code => { | ||
t.equal(code, 1006) | ||
t.end() | ||
@@ -723,0 +717,0 @@ }) |
@@ -6,3 +6,2 @@ /// <reference types="node" /> | ||
import * as WebSocket from 'ws'; | ||
import { Duplex, DuplexOptions } from 'stream'; | ||
import { FastifyReply } from 'fastify/types/reply'; | ||
@@ -84,12 +83,8 @@ import { preCloseHookHandler, preCloseAsyncHookHandler } from 'fastify/types/hooks'; | ||
this: FastifyInstance<Server, IncomingMessage, ServerResponse>, | ||
connection: SocketStream, | ||
socket: WebSocket.WebSocket, | ||
request: FastifyRequest<RequestGeneric, RawServer, RawRequest, SchemaCompiler, TypeProvider, ContextConfig, Logger> | ||
) => void | Promise<any>; | ||
export interface SocketStream extends Duplex { | ||
socket: WebSocket; | ||
} | ||
export interface WebsocketPluginOptions { | ||
errorHandler?: (this: FastifyInstance, error: Error, connection: SocketStream, request: FastifyRequest, reply: FastifyReply) => void; | ||
errorHandler?: (this: FastifyInstance, error: Error, socket: WebSocket.WebSocket, request: FastifyRequest, reply: FastifyReply) => void; | ||
options?: WebSocketServerOptions; | ||
connectionOptions?: DuplexOptions; | ||
preClose?: preCloseHookHandler | preCloseAsyncHookHandler; | ||
@@ -96,0 +91,0 @@ } |
@@ -1,6 +0,6 @@ | ||
import fastifyWebsocket, { WebsocketHandler, SocketStream, fastifyWebsocket as namedFastifyWebsocket, default as defaultFastifyWebsocket } from '..'; | ||
import fastifyWebsocket, { WebsocketHandler, fastifyWebsocket as namedFastifyWebsocket, default as defaultFastifyWebsocket } from '..'; | ||
import type { IncomingMessage } from "http"; | ||
import fastify, { RouteOptions, FastifyRequest, FastifyInstance, FastifyReply, RequestGenericInterface, FastifyBaseLogger, RawServerDefault, FastifySchema, RawRequestDefaultExpression } from 'fastify'; | ||
import { expectType } from 'tsd'; | ||
import { Server } from 'ws'; | ||
import { Server, WebSocket } from 'ws'; | ||
import { RouteGenericInterface } from 'fastify/types/route'; | ||
@@ -15,6 +15,6 @@ import { TypeBoxTypeProvider } from '@fastify/type-provider-typebox'; | ||
app.register(fastifyWebsocket, { | ||
errorHandler: function errorHandler(error: Error, connection: SocketStream, request: FastifyRequest, reply: FastifyReply): void { | ||
errorHandler: function errorHandler(error: Error, socket: WebSocket, request: FastifyRequest, reply: FastifyReply): void { | ||
expectType<FastifyInstance>(this); | ||
expectType<Error>(error) | ||
expectType<SocketStream>(connection) | ||
expectType<WebSocket>(socket) | ||
expectType<FastifyRequest>(request) | ||
@@ -28,5 +28,5 @@ expectType<FastifyReply>(reply) | ||
app.get('/websockets-via-inferrence', { websocket: true }, async function (connection, request) { | ||
app.get('/websockets-via-inferrence', { websocket: true }, async function (socket, request) { | ||
expectType<FastifyInstance>(this); | ||
expectType<SocketStream>(connection); | ||
expectType<WebSocket>(socket); | ||
expectType<Server>(app.websocketServer); | ||
@@ -38,4 +38,4 @@ expectType<FastifyRequest<RequestGenericInterface>>(request) | ||
const handler: WebsocketHandler = async (connection, request) => { | ||
expectType<SocketStream>(connection); | ||
const handler: WebsocketHandler = async (socket, request) => { | ||
expectType<WebSocket>(socket); | ||
expectType<Server>(app.websocketServer); | ||
@@ -66,4 +66,4 @@ expectType<FastifyRequest<RequestGenericInterface>>(request) | ||
}, | ||
wsHandler: (connection, request) => { | ||
expectType<SocketStream>(connection); | ||
wsHandler: (socket, request) => { | ||
expectType<WebSocket>(socket); | ||
expectType<FastifyRequest<RouteGenericInterface>>(request); | ||
@@ -81,4 +81,4 @@ expectType<boolean>(request.ws); | ||
}, | ||
wsHandler: (connection, request) => { | ||
expectType<SocketStream>(connection); | ||
wsHandler: (socket, request) => { | ||
expectType<WebSocket>(socket); | ||
expectType<FastifyRequest<RouteGenericInterface>>(request) | ||
@@ -92,4 +92,4 @@ }, | ||
websocket: true | ||
}, async (connection, request) => { | ||
expectType<SocketStream>(connection); | ||
}, async (socket, request) => { | ||
expectType<WebSocket>(socket); | ||
expectType<{ foo: string }>(request.params); | ||
@@ -111,4 +111,4 @@ expectType<{ bar: string }>(request.body); | ||
}, | ||
wsHandler: (connection, request) => { | ||
expectType<SocketStream>(connection); | ||
wsHandler: (socket, request) => { | ||
expectType<WebSocket>(socket); | ||
expectType<{ foo: string }>(request.params); | ||
@@ -149,4 +149,4 @@ expectType<{ bar: string }>(request.body); | ||
}, | ||
wsHandler: (connection, request) => { | ||
expectType<SocketStream>(connection); | ||
wsHandler: (socket, request) => { | ||
expectType<WebSocket>(socket); | ||
expectType<{ foo: string }>(request.params); | ||
@@ -161,5 +161,5 @@ expectType<{ bar: string }>(request.body); | ||
{ websocket: true }, | ||
async function (connection, request) { | ||
async function (socket, request) { | ||
expectType<FastifyInstance>(this); | ||
expectType<SocketStream>(connection); | ||
expectType<WebSocket>(socket); | ||
expectType<Server>(app.websocketServer); | ||
@@ -166,0 +166,0 @@ expectType<FastifyRequest<RequestGenericInterface, RawServerDefault, RawRequestDefaultExpression, FastifySchema, TypeBoxTypeProvider, unknown, FastifyBaseLogger>>(request); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
386
87235
1966