Add websocket logic server
- Websocket callback binding
- Websocket send message to specific connected socket
GitLab: #53
Change-Id: Ib52db5d99b0bc3ad4d1a775a62fecb9ea3b4d132
diff --git a/server/src/jamid/jamid.ts b/server/src/jamid/jamid.ts
index 27ff0e3..ee91ad4 100644
--- a/server/src/jamid/jamid.ts
+++ b/server/src/jamid/jamid.ts
@@ -138,6 +138,8 @@
// 2. You cannot specify multiple handlers for the same event
// 3. You cannot specify a default handler
this.jamiSwig.init(handlers);
+
+ // TODO: Bind websocket callbacks for webrtc action on Incoming account message
}
stop() {
@@ -189,7 +191,7 @@
sendAccountTextMessage(accountId: string, contactId: string, type: string, message: string) {
const messageStringMap: StringMap = new this.jamiSwig.StringMap();
- messageStringMap.set(type, message);
+ messageStringMap.set(type, JSON.stringify(message));
this.jamiSwig.sendAccountTextMessage(accountId, contactId, messageStringMap);
}
@@ -313,7 +315,7 @@
this.events.onMessageReceived.subscribe((signal) => {
log.debug('Received MessageReceived:', JSON.stringify(signal));
- // TODO: Send message to client using WebSocket
+ // TODO: Send message to client using WS service
});
}
}
diff --git a/server/src/ws.ts b/server/src/ws.ts
index eadbab0..0081e59 100644
--- a/server/src/ws.ts
+++ b/server/src/ws.ts
@@ -18,6 +18,7 @@
import { IncomingMessage } from 'node:http';
import { Duplex } from 'node:stream';
+import { WebSocketMessage, WebSocketMessageType } from 'jami-web-common';
import { jwtVerify } from 'jose';
import log from 'loglevel';
import { Service } from 'typedi';
@@ -28,16 +29,34 @@
@Service()
export class Ws {
- constructor(private readonly vault: Vault) {}
+ private sockets: Map<string, WebSocket[]>;
+ private callbacks: Map<WebSocketMessageType, ((message: WebSocketMessage) => void)[]>;
+
+ constructor(private readonly vault: Vault) {
+ this.sockets = new Map();
+ this.callbacks = new Map();
+ }
async build() {
const wss = new WebSocketServer({ noServer: true });
+
wss.on('connection', (ws: WebSocket, _req: IncomingMessage, accountId: string) => {
log.info('New connection', accountId);
- // TODO: Add the account ID here to a map of accountId -> WebSocket connections
+ const accountSockets = this.sockets.get(accountId);
+ if (accountSockets) {
+ accountSockets.push(ws);
+ } else {
+ this.sockets.set(accountId, [ws]);
+ }
- ws.on('message', (_data) => {
- ws.send(JSON.stringify({ accountId }));
+ ws.on('message', (messageString: string) => {
+ const message: WebSocketMessage = JSON.parse(messageString);
+ const callbacks = this.callbacks.get(message.type);
+ if (callbacks) {
+ for (const callback of callbacks) {
+ callback(message);
+ }
+ }
});
});
@@ -67,4 +86,24 @@
});
};
}
+
+ bind(messageType: WebSocketMessageType, callback: (message: WebSocketMessage) => void): void {
+ const messageTypeCallbacks = this.callbacks.get(messageType);
+ if (messageTypeCallbacks) {
+ messageTypeCallbacks.push(callback);
+ } else {
+ this.callbacks.set(messageType, [callback]);
+ }
+ }
+
+ send(accountId: string, message: WebSocketMessage): boolean {
+ const accountSockets = this.sockets.get(accountId);
+ if (!accountSockets) {
+ return false;
+ }
+ for (const accountSocket of accountSockets) {
+ accountSocket.send(message);
+ }
+ return true;
+ }
}