1 import * as X2JS from 'x2js';
\r
3 const socketUrl = [location.protocol === 'https:' ? 'wss://' : 'ws://', 'admin', ':', 'admin', '@', location.hostname, ':', location.port, '/websocket'].join('');
\r
4 const subscriptions: { [scope: string]: SubscriptionCallback[] } = { };
\r
6 export interface IFormatedMessage {
\r
7 notifType: string | null;
\r
11 export type SubscriptionCallback<TMessage extends IFormatedMessage = IFormatedMessage> = (msg: TMessage) => void;
\r
13 function formatData(event: MessageEvent) : IFormatedMessage | undefined {
\r
15 var x2js = new X2JS();
\r
16 var jsonObj: { [key: string]: IFormatedMessage } = x2js.xml2js(event.data);
\r
17 if (jsonObj && typeof (jsonObj) === 'object') {
\r
19 const notifType = Object.keys(jsonObj)[0];
\r
20 const formated = jsonObj[notifType];
\r
21 formated.notifType = notifType ;
\r
22 formated.time = new Date().toISOString();
\r
29 export function subscribe<TMessage extends IFormatedMessage = IFormatedMessage>(scope: string | string[], callback: SubscriptionCallback<TMessage>): Promise<boolean> {
\r
30 return socketReady.then((notificationSocket) => {
\r
31 const scopes = scope instanceof Array ? scope : [scope];
\r
33 // send all new scopes to subscribe
\r
34 const newScopesToSubscribe: string[] = scopes.reduce((acc: string[], cur: string) => {
\r
35 const currentCallbacks = subscriptions[cur];
\r
36 if (currentCallbacks) {
\r
37 if (!currentCallbacks.some(c => c === callback)) {
\r
38 currentCallbacks.push(callback);
\r
41 subscriptions[cur] = [callback];
\r
47 if (newScopesToSubscribe.length === 0) {
\r
51 // send a subscription to all active scopes
\r
52 const scopesToSubscribe = Object.keys(subscriptions);
\r
53 if (notificationSocket.readyState === notificationSocket.OPEN) {
\r
56 'scopes': scopesToSubscribe
\r
58 notificationSocket.send(JSON.stringify(data));
\r
65 export function unsubscribe<TMessage extends IFormatedMessage = IFormatedMessage>(scope: string | string[], callback: SubscriptionCallback<TMessage>): Promise<boolean> {
\r
66 return socketReady.then((notificationSocket) => {
\r
67 const scopes = scope instanceof Array ? scope : [scope];
\r
68 scopes.forEach(s => {
\r
69 const callbacks = subscriptions[s];
\r
70 const index = callbacks && callbacks.indexOf(callback);
\r
72 callbacks.splice(index, 1);
\r
74 if (callbacks.length === 0) {
\r
75 subscriptions[s] === undefined;
\r
79 // send a subscription to all active scopes
\r
80 const scopesToSubscribe = Object.keys(subscriptions);
\r
81 if (notificationSocket.readyState === notificationSocket.OPEN) {
\r
84 'scopes': scopesToSubscribe
\r
86 notificationSocket.send(JSON.stringify(data));
\r
93 const connect = (): Promise<WebSocket> => {
\r
94 return new Promise((resolve, reject) => {
\r
95 const notificationSocket = new WebSocket(socketUrl);
\r
97 notificationSocket.onmessage = (event) => {
\r
98 // process received event
\r
99 if (typeof event.data === 'string') {
\r
100 const formated = formatData(event);
\r
101 if (formated && formated.notifType) {
\r
102 const callbacks = subscriptions[formated.notifType];
\r
104 callbacks.forEach(cb => {
\r
105 // ensure all callbacks will be called
\r
107 return cb(formated);
\r
109 console.error(reason);
\r
117 notificationSocket.onerror = function (error) {
\r
118 console.log("Socket error: " + error);
\r
119 reject("Socket error: " + error);
\r
122 notificationSocket.onopen = function (event) {
\r
123 console.log("Socket connection opened.");
\r
124 resolve(notificationSocket);
\r
127 notificationSocket.onclose = function (event) {
\r
128 socketReady = connect();
\r
133 let socketReady = connect();
\r