SpaceNode
SpaceNode includes a built-in WebSocket server (RFC 6455) with zero external dependencies. Supports fragment assembly, ping/pong heartbeat, and backpressure.
import { createApp } from 'SpaceNode'
const app = await createApp()
app.ws('/chat', (socket, req, services) => {
console.log('Client connected')
socket.on('message', (msg) => {
console.log('Received:', msg)
socket.send(`Echo: ${msg}`)
})
socket.on('close', () => {
console.log('Client disconnected')
})
})
app.listen(3000)
services gives you access to all registered services, same as in HTTP controllers.| Method / Property | Description |
|---|---|
socket.send(data) | Send text (string) or binary (Buffer). Returns false on backpressure |
socket.close(code?) | Close connection (default code 1000) |
socket.pause() | Pause receiving data (for backpressure from consumer side) |
socket.resume() | Resume receiving data after pause |
socket.on('message', fn) | Receive messages (string for text, Buffer for binary) |
socket.on('close', fn) | Connection closed |
socket.on('error', fn) | Connection error |
socket.on('ping', fn) | Ping frame received |
socket.on('pong', fn) | Pong frame received |
socket.readyState | 0=CONNECTING, 1=OPEN, 2=CLOSING, 3=CLOSED |
socket.send() returns a boolean — false means the socket buffer is full. Use pause() / resume() to manage flow control:
const ok = socket.send('hello')
if (!ok) {
socket.pause() // pause reading until drain
}
Restrict which origins can establish WebSocket connections:
const app = await createApp({
wsOrigins: ['https://mysite.com', 'https://admin.mysite.com'],
})
Large messages may arrive as multiple WebSocket frames (fragments). SpaceNode automatically reassembles fragments into complete messages before emitting the 'message' event.
SpaceNode automatically sends ping frames every 30 seconds to keep connections alive. Clients that don't respond with a pong within 60 seconds are disconnected.
app
.ws('/chat', chatHandler)
.ws('/notifications', notifyHandler)
.ws('/live-data', dataHandler)
const clients = new Set()
app.ws('/chat', (socket) => {
clients.add(socket)
socket.on('message', (msg) => {
// Broadcast to all connected clients
for (const client of clients) {
if (client !== socket && client.readyState === 1) {
client.send(msg)
}
}
})
socket.on('close', () => clients.delete(socket))
})
// Browser JavaScript
const ws = new WebSocket('ws://localhost:3000/chat')
ws.onopen = () => ws.send('Hello!')
ws.onmessage = (e) => console.log('Server says:', e.data)
node:http upgrade event + node:crypto for the WebSocket handshake. Supports text and binary frames, fragment assembly, ping/pong heartbeat (30s/60s), backpressure detection, origin validation, and close frames per RFC 6455. Zero external dependencies.