class MessageRouter { /** * @param {ConnectionManager} connectionManager An instance of ConnectionManager. */ constructor(connectionManager) { this.connectionManager = connectionManager; } /** * Routes the incoming message based on its content. * * The expected JSON structure: * { * type: "private" | "broadcast" | "other", * payload: { * u: "recipient username", // for private messages * body: "...", // message body * // additional fields for other types can be added too * } * } * * If 'type' is omitted, it defaults to "private". */ routeMessage(fromUser, data) { const type = data.type || 'private'; switch (type) { case 'private': this.handlePrivateMessage(fromUser, data.payload); break; case 'broadcast': this.handleBroadcastMessage(fromUser, data.payload); break; default: this.sendError(fromUser, `Unknown message type: ${type}`); } } handlePrivateMessage(fromUser, payload) { if (!payload || !payload.u || !payload.body) { return this.sendError(fromUser, "Invalid payload for a private message. Required: { u, body }"); } const recipientSocket = this.connectionManager.getUserSocket(payload.u); if (recipientSocket && recipientSocket.readyState === recipientSocket.OPEN) { recipientSocket.send(JSON.stringify({ error: false, message: { from: fromUser, body: payload.body } })); } else { this.sendError(fromUser, `User ${payload.u} is not online`); } } handleBroadcastMessage(fromUser, payload) { if (!payload || !payload.body) { return this.sendError(fromUser, "Invalid payload for broadcast message. Required: { body }"); } const msg = { error: false, message: { from: fromUser, body: payload.body } }; this.connectionManager.broadcast(msg, fromUser); } sendError(toUser, errorMessage) { const ws = this.connectionManager.getUserSocket(toUser); if (ws && ws.readyState === ws.OPEN) { ws.send(JSON.stringify({ error: true, message: errorMessage })); } } } module.exports = MessageRouter;