AdonisJS Websocket
node ace add adonisjs-websocket
Usage
Simple example:
router.ws('/ws', ({ ws }) => {
ws.on('message', (message) => {
ws.send('Received: ' + message.toString())
})
ws.on('close', () => {
console.log('Connection closed')
})
ws.send('Hello! Your id is ' + ws.id)
})
npx wscat -c "ws://localhost:3333/ws"
Middleware and broadcasting:
router.ws(
'/rooms/:roomId',
({ ws, params, auth }) => {
const roomId = params.roomId
const user = auth.user
if (user.isBanned) {
return ws.close()
}
ws.on('message', (message) => {
ws.send('Received: ' + message.toString())
})
await ws.broadcast('Hello everyone!')
},
[
() => import('#middleware/container_bindings_middleware'),
() => import('@adonisjs/auth/initialize_auth_middleware'),
middleware.auth(),
]
)
npx wscat -c 'ws://localhost:3333/rooms/1' -H 'Authorization: Bearer oat_MjU.Z25o...'
npx wscat -c 'ws://localhost:3333/rooms/2?token=oat_MjU.Z25o...'
npx wscat -c 'ws://localhost:3334/rooms/2?token=oat_MjU.Z25o...'
Using controllers:
const WsChatController = () => import('#controllers/ws/chat_controller')
router.ws('/chat', [WsChatController, 'handle'])
import type { WebSocketContext } from 'adonisjs-websocket'
export default class ChatController {
public async handle({ ws }: WebSocketContext) {
ws.on('message', (message) => {
ws.send('Received: ' + message.toString())
})
ws.send('Hello! Your id is ' + ws.id)
}
}
For browsers, it's common practice to send a small message (heartbeat) for every given time passed (e.g every 30sec) to keep the connection active.
const ws = new WebSocket('wss://localhost:3333/ws')
const HEARTBEAT_INTERVAL = 30000
let heartbeatInterval
ws.onopen = () => {
heartbeatInterval = setInterval(() => {
ws.send('ping')
}, HEARTBEAT_INTERVAL)
}
ws.onclose = () => {
clearInterval(heartbeatInterval)
}
router.ws('/ws', ({ ws }) => {
ws.on('message', (message) => {
if (message.toString() === 'ping') {
ws.send('pong')
}
})
})