WebSocket
Analog also supports WebSockets
and Server-Sent Events
through Nitro.
Enabling WebSockets
Currently, WebSocket support in Nitro is experimental and it can be enabled in the analog
plugin:
vite.config.ts
import { defineConfig } from 'vite';
import analog from '@analogjs/platform';
export default defineConfig({
// ...
plugins: [
analog({
// ...
nitro: {
experimental: {
websocket: true,
},
},
}),
],
// ...
});
Note: In development, the Vite HMR WebSocket server runs on the same port as the dev server by default. To prevent conflicts, you need to change this port. The dev server port is usually defined in project.json
/angular.json
, which takes precedence over vite.config.ts
. To allow the port settings in vite.config.ts
to take effect, remove the port definition from project.json
/angular.json
. Additionally, you can specify an optional path to easily differentiate connections in the browser dev tools:
vite.config.ts
import { defineConfig } from 'vite';
import analog from '@analogjs/platform';
export default defineConfig({
// ...
server: {
port: 3000, // dev-server port
hmr: {
port: 3002, // hmr ws port
path: 'vite-hmr', // optional
},
},
// ...
});
Defining a WebSocket Handler
Similar to API routes, WebSocket Handlers are defined in the src/server/routes
folder.
// src/server/routes/ws/chat.ts
import { defineWebSocketHandler } from 'h3';
export default defineWebSocketHandler({
open(peer) {
peer.send({ user: 'server', message: `Welcome ${peer}!` });
peer.publish('chat', { user: 'server', message: `${peer} joined!` });
peer.subscribe('chat');
},
message(peer, message) {
if (message.text().includes('ping')) {
peer.send({ user: 'server', message: 'pong' });
} else {
const msg = {
user: peer.toString(),
message: message.toString(),
};
peer.send(msg); // echo
peer.publish('chat', msg);
}
},
close(peer) {
peer.publish('chat', { user: 'server', message: `${peer} left!` });
},
});
WebSocket Routes
Analog's internal API middleware is not applied to WebSocket routes, therefore, WebSocket routes are exposed without the /api
prefix.
For example, src/server/routes/ws/chat.ts
is exposed as ws://example.com/ws/chat
instead of ws://example.com/api/ws/chat
Defining a Server-sent Event Handler
Server-sent event handlers can be created using createEventStream
function in the event handler.
// src/server/routes/sse.ts
import { defineEventHandler, createEventStream } from 'h3';
export default defineEventHandler(async (event) => {
const eventStream = createEventStream(event);
const interval = setInterval(async () => {
await eventStream.push(`Message @ ${new Date().toLocaleTimeString()}`);
}, 1000);
eventStream.onClosed(async () => {
clearInterval(interval);
await eventStream.close();
});
return eventStream.send();
});
More Info
WebSockets are powered by Nitro, h3 and crossws. See the Nitro, h3 and crossws docs for more details.