Usage
defineWSHandler
The all-in-one utility to manage reactive WebSocket connections from server-side.
The defineWSHandler
will be the main utility to manage WebSocket connections server-side. It handles automatically the subscription of topics defined in the runtime configuration while also proving a hooking system to trigger messages globally from other part of the application server-side.
Please first read the upstream Nitro documentation on
defineWebSocketHandler
to understand the basic usage.Example
/server/routes/_ws.ts
import * as v from 'valibot'
export default defineWSHandler({
async open(peer) {
// Update peer with 'chat' data from storage
const chat = await useStorage('ws').getItem('chat')
if (chat)
peer.send(JSON.stringify({
topic: 'chat',
payload: chat,
}), { compress: true })
// Update everyone's session metadata
const payload = JSON.stringify({ topic: 'session', payload: { users: peer.peers.size } })
peer.send(payload, { compress: true })
peer.publish('session', payload, { compress: true })
},
async message(peer, message) {
// Validate the incoming chat message
const parsedMessage = await wsValidateMessage( // built-in validation util
v.object({
type: v.literal('publish'),
topic: v.literal('chat'),
payload: v.object({ text: v.string() }),
}),
message,
)
// Update chat data in storage
const mem = useStorage('ws')
const { topic, payload } = parsedMessage
const _chat = await mem.getItem<Array<{ user: string, text: string }>>('chat') || []
const newChat = [..._chat, { ...payload, user: peer.id }]
await mem.setItem(topic, newChat)
// Broadcast the updated chat to everyone
peer.send(JSON.stringify({ topic, payload: newChat }), { compress: true })
peer.publish(topic, JSON.stringify({ topic, payload: newChat }), { compress: true })
},
close(peer) {
// Update everyone's session metadata
peer.publish(
'session',
JSON.stringify({
topic: 'session',
payload: {
users: peer.peers.size,
},
}),
{ compress: true },
)
},
})
Parsing messages
A small wsParseMessage
utility is provided to parse JSON content from incoming messages. This uses destr
under the hood to parse the message and not throw an error if the message is not a valid JSON string.
This is also used under the hood by validation utilities.
Authentication
You can easily validate user's sessions with modules like nuxt-auth-utils
as described in the documentation.
Please refer to the reactive-ws
demo for a complete example.