Skip to main content

Guide: Adding a WebSocket Stream

This guide explains how to create a new real-time data stream (e.g., "Live Horse Heart Rate").

1. Create a WS Controller

Create a new file in app/Controllers/Ws/HeartRateController.ts. It should handle the lifecycle of the stream.

import { Socket } from "socket.io";

export class HeartRateController {
private intervals: Map<string, NodeJS.Timeout> = new Map();

public startStream(socket: Socket, data: { horseId: number }) {
// 1. Validate Input
if (!data.horseId) return;

// 2. Clear existing stream for this socket if needed
this.cleanup(socket);

// 3. Start Data Fetching Loop
const interval = setInterval(async () => {
// Fetch data
const bpm = Math.floor(Math.random() * (60 - 40) + 40); // Fake data

// Emit to Client
socket.emit(`heartRate:${data.horseId}`, { bpm, timestamp: Date.now() });
}, 1000);

// 4. Store interval to clear it later
this.intervals.set(socket.id, interval);
}

public cleanup(socket: Socket) {
if (this.intervals.has(socket.id)) {
clearInterval(this.intervals.get(socket.id));
this.intervals.delete(socket.id);
}
}
}

2. Register Route

Open start/ws_routes.ts and wire up the events.

import { HeartRateController } from "#controllers/ws/heart_rate_controller";

export default function defineWsRoutes(socket: Socket) {
const hrController = new HeartRateController();

// Start Stream
socket.on("startHeartRate", (data) => hrController.startStream(socket, data));

// Stop/Disconnect
socket.on("stopHeartRate", () => hrController.cleanup(socket));
socket.on("disconnect", () => hrController.cleanup(socket));
}

3. Client Usage

const socket = io("https://api.firstbreath.fr");

socket.emit("startHeartRate", { horseId: 123 });

socket.on("heartRate:123", (data) => {
console.log("Current BPM:", data.bpm);
});