import WebSocket from 'ws'; import http from 'http'; import { AddressInfo } from 'net'; import { DispatcherClientRoles, DispatcherIpcMessages } from './constants.js'; import { connectedInstances, WebSocketInstance } from './connected-instances.js'; import { intercept, restHandler, shouldBeIntercepted } from './rest-handler.js'; import { isJsonRpcMessage, isServiceMessage } from './utils.js'; const dispatcher = http.createServer(restHandler); const wss = new WebSocket.Server({ server: dispatcher }); wss.on('connection', (ws) => { ws.on('message', (rawMessage) => { // We work only with text messages const message = rawMessage.toString(); console.log(`Received WS message: ${message}`); const messageObject = JSON.parse(message); if (isServiceMessage(messageObject)) { handleServiceMessage(messageObject, ws); } if (isJsonRpcMessage(messageObject)) { handleJsonRpcMessage(message, messageObject, ws); } }); }); /** * Handles service messages. Currently, there is only one type of service message: a message that includes the `role`. * * Based on role we setup `connectedInstances`. */ function handleServiceMessage(messageObject: any, wsInstance: WebSocketInstance) { if (messageObject.role === DispatcherClientRoles.UNIFIED_CLIENT) { connectedInstances.unifiedAblyClient = wsInstance; } else if (messageObject.role === DispatcherClientRoles.ADAPTER) { connectedInstances.adapter = wsInstance; process.send?.(DispatcherIpcMessages.ADAPTER_CONNECTED); } } /** * Handles service messages. Currently, there is only one type of service message: a message that includes the `role`. * * Based on role we setup `connectedInstances`. */ function handleJsonRpcMessage(message: string, messageObject: any, wsInstance: WebSocketInstance) { if (shouldBeIntercepted(messageObject.id)) { intercept(messageObject); } else if (wsInstance === connectedInstances.unifiedAblyClient) { connectedInstances.adapter?.send(message); } else if (wsInstance === connectedInstances.adapter) { connectedInstances.unifiedAblyClient?.send(message); } } dispatcher.listen(3000, () => { console.log(`Server started on ${(dispatcher.address() as AddressInfo).port}`); process.send?.(DispatcherIpcMessages.DISPATCHER_STARTED); });