import { Injectable } from '@angular/core'; import { DatePipe } from '@angular/common'; import { HermesSocketService } from './hermes-socket.service'; import EventService from './shared/services/EventService'; export interface Message { d: object, t: object, o: object } @Injectable({ providedIn: 'root' }) export class HermesClientService { pipe = new DatePipe('en-US') connected: boolean; logged_in: boolean; private subscriptions: { [key: number]: ((data: any) => void)[] } constructor(private socket: HermesSocketService, private events: EventService) { this.subscriptions = {}; this.connected = false; this.logged_in = false; this.events.listen('tts_login', (payload) => { this.login(payload); }); } public connect() { if (this.connected) return; this.socket.connect(); this.connected = true; return this.listen(); } public disconnect() { if (!this.connected) return; this.connected = false; this.logged_in = false; this.socket.close(); this.events.emit('tts_logoff', null); } private send(op: number, data: any) { if (op != 0) console.log("TX:", data); this.socket.sendMessage({ d: data, op }); } public login(api_key: string) { if (!this.connected) this.connect(); if (this.logged_in) return; this.send(1, { api_key, web_login: true, major_version: 0, minor_version: 1 }); } public createPolicy(groupId: string, path: string, usage: number, timespan: number) { if (!this.logged_in) return; this.send(3, { request_id: null, type: "create_policy", data: { groupId, path, count: usage, span: timespan }, }); } public deletePolicy(id: string) { if (!this.logged_in) return; this.send(3, { request_id: null, type: "delete_policy", data: { id }, }); } public fetchPolicies() { if (!this.logged_in) return; this.send(3, { request_id: null, type: "get_policies", data: null, }); } public fetchPermissionsAndGroups() { if (!this.logged_in) return; this.send(3, { request_id: null, type: "get_permissions", data: null, }); } public heartbeat() { const date = new Date() this.send(0, { date_time: this.pipe.transform(date.getTime() + date.getUTCDate(), "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'SSS'Z'") }); } public subscribe(code: number, action: (data: any) => void) { if (!(code in this.subscriptions)) { this.subscriptions[code] = [] } this.subscriptions[code].push(action); } public updatePolicy(id: string, groupId: string, path: string, usage: number, timespan: number) { if (!this.logged_in) return; this.send(3, { request_id: null, type: "update_policy", data: { id, groupId, path, count: usage, span: timespan }, }); } private listen() { return this.socket.subscribe({ next: (message: any) => { console.log("RX:", message); switch (message.op) { case 0: // Heartbeat console.log("Heartbeat received. Potential connection problem?"); break; case 2: // Login Ack console.log("Login successful."); this.logged_in = true; this.events.emit('tts_login_ack', null); break; case 4: // Request Ack console.log("Request received."); break; } if (message.op in this.subscriptions) { console.log('found #' + message.op + ' subscription for ' + message.op); for (let action of this.subscriptions[message.op]) action(message.d); } }, error: (err: any) => console.error('Websocket error', err), complete: () => console.log('Websocket disconnected.') }); } }