UNPKG

@hathora/server-sdk

Version:

![Hathora Logo](https://user-images.githubusercontent.com/7004280/223056895-c16419d2-2b91-4013-82f0-7616c84d31b7.svg)

73 lines (72 loc) 2.83 kB
import uWS from "uWebSockets.js"; import jwt from "jsonwebtoken"; const socketsMap = new Map(); export function startServer(app, port) { return new Promise((resolve, reject) => { const server = uWS .App() .ws("/:roomId", { upgrade: async (res, req, context) => { const roomId = req.getParameter(0); const queryParts = req.getQuery().split("token="); if (queryParts.length !== 2) { res.writeStatus("401").end(); return; } const token = queryParts[1]; const userId = await app.verifyToken(token, roomId); if (userId === undefined) { res.writeStatus("401").end(); return; } if (socketsMap.has(roomId + userId)) { res.writeStatus("400").end(); return; } res.upgrade({ roomId, userId }, req.getHeader("sec-websocket-key"), req.getHeader("sec-websocket-protocol"), req.getHeader("sec-websocket-extensions"), context); }, open: (ws) => { const { roomId, userId } = ws.getUserData(); ws.subscribe(roomId); socketsMap.set(roomId + userId, ws); app.subscribeUser(roomId, userId); }, message: (ws, message) => { const { roomId, userId } = ws.getUserData(); app.onMessage(roomId, userId, message); }, close: (ws) => { const { roomId, userId } = ws.getUserData(); socketsMap.delete(roomId + userId); app.unsubscribeUser(roomId, userId); }, }) .listen(port, (listenSocket) => { if (listenSocket) { resolve({ sendMessage: (roomId, userId, data) => { socketsMap.get(roomId + userId)?.send(data, true); }, broadcastMessage: (roomId, data) => { server.publish(roomId, data, true); }, closeConnection: (roomId, userId, error) => { socketsMap.get(roomId + userId)?.end(4000, error); }, }); } else { reject(`Server failed to start, is the port ${port} already in use?`); } }); }); } export function verifyJwt(token, secret, userIdField = "id") { try { const payload = jwt.verify(token, secret); if (typeof payload === "object" && typeof payload.id === "string") { return payload[userIdField]; } } catch (e) { } }