import {Injectable} from '@angular/core'; import {Host} from './host'; import {ChatMessage} from './chat.message'; import {SocketRegistrationMessage} from './socket.registration.message'; import {SocketReceivedMessage} from './socket.received.message'; import {WebsocketListener} from './websocket.listener'; import {SocketSendMessage} from './socket.send.message'; import {SocketKeepaliveMessage} from './socket.keepalive.message'; @Injectable({ providedIn: 'root' }) export class WebsocketService { private socket: WebSocket = new WebSocket(Host.WEBSOCKET); private userList: Map = new Map(); private listener: WebsocketListener; private chatToken: string; initializeSocket(chatToken: string): void { this.chatToken = chatToken; this.socket = new WebSocket(Host.WEBSOCKET); this.socket.addEventListener('open', () => { this.authorize(); }); this.socket.addEventListener('message', (transmission: MessageEvent) => { this.handleIncomingTransmission(transmission); }); this.socket.addEventListener( 'close', () => { this.initializeSocket(this.chatToken); this.authorize(); } ); } setListener(listener: WebsocketListener): void { this.listener = listener; } sendChatMessage(message: string): void { const socketMessage: SocketSendMessage = { type: Response.CHAT_MESSAGE, message }; this.socket.send(JSON.stringify(socketMessage)); } sendKeepAliveMessage(): void { const socketMessage: SocketKeepaliveMessage = { type: Response.KEEP_ALIVE }; this.socket.send(JSON.stringify(socketMessage)); } private authorize(): void { const message: SocketRegistrationMessage = {type: Response.REGISTRATION_MESSAGE, token: this.chatToken}; this.socket.send(JSON.stringify(message)); } private handleIncomingTransmission(transmission: MessageEvent): void { const response = JSON.parse(transmission.data); switch (response.type) { case Response.CHAT_MESSAGE: const messageReceived: SocketReceivedMessage = response; const message: ChatMessage = { userId: messageReceived.userId, username: this.userList.get(messageReceived.userId), datetime: messageReceived.datetime, message: messageReceived.message }; this.listener.onChatMessage(message); break; case Response.REGISTRATION_MESSAGE: this.userList.set(response.userId, response.username); break; case Response.USERLIST: response.users.forEach( (user) => { this.userList.set(user.userId, user.username); } ); break; default: throw new Error('Unknown message type: ' + response.type); } } } enum Response { CHAT_MESSAGE = 1, REGISTRATION_MESSAGE, USERLIST, KEEP_ALIVE }