- Prisma: Device model (Quest/Phone, online status, battery, storage, game/streaming/cortex state), Video model with likes, VideoLike - Signaling WebSocket for SDP/ICE relay and device presence - Device routes: list, status, delete - Content routes: video CRUD with range-support streaming - SignalingManager service for device socket registry and heartbeat
34 lines
1.1 KiB
TypeScript
34 lines
1.1 KiB
TypeScript
import { FastifyPluginAsync } from 'fastify';
|
|
import { verifyAccessToken } from '../../plugins/auth.js';
|
|
import { SignalingManager } from '../../services/signaling-manager.service.js';
|
|
|
|
export function createSignalingRoutes(signalingManager: SignalingManager): FastifyPluginAsync {
|
|
const signalingRoutes: FastifyPluginAsync = async (fastify) => {
|
|
// GET /signaling/ws?token=<accessToken>
|
|
fastify.get('/signaling/ws', { websocket: true }, async (socket, request) => {
|
|
const url = new URL(request.url, `http://${request.headers.host}`);
|
|
const token = url.searchParams.get('token');
|
|
|
|
if (!token) {
|
|
socket.send(JSON.stringify({ type: 'error', error: 'Missing token' }));
|
|
socket.close();
|
|
return;
|
|
}
|
|
|
|
let userId: string;
|
|
try {
|
|
userId = await verifyAccessToken(token);
|
|
} catch {
|
|
socket.send(JSON.stringify({ type: 'error', error: 'Invalid or expired token' }));
|
|
socket.close();
|
|
return;
|
|
}
|
|
|
|
request.log.info({ userId }, 'Signaling WebSocket connected');
|
|
await signalingManager.handleConnection(userId, socket);
|
|
});
|
|
};
|
|
|
|
return signalingRoutes;
|
|
}
|