psi-socket-io
Version:
Socket.IO module for Angular
91 lines (74 loc) • 2.78 kB
text/typescript
import { Inject } from '@angular/core';
import { Observable } from 'rxjs';
import { share } from 'rxjs/operators';
import * as io from 'socket.io-client';
import { SocketIoConfig } from './config/socket-io.config';
export class WrappedSocket {
subscribersCounter: Record<string, number> = {};
eventObservables$: Record<string, Observable<any>> = {};
ioSocket: any;
emptyConfig: SocketIoConfig = {
url: '',
options: {}
};
constructor(private config: SocketIoConfig) {
if (config === undefined) {
config = this.emptyConfig;
}
const url: string = config.url;
const options: any = config.options;
const ioFunc = (io as any).default ? (io as any).default : io;
this.ioSocket = ioFunc(url, options);
}
of(namespace: string) {
this.ioSocket.of(namespace);
}
on(eventName: string, callback: Function) {
this.ioSocket.on(eventName, callback);
}
once(eventName: string, callback: Function) {
this.ioSocket.once(eventName, callback);
}
connect() {
return this.ioSocket.connect();
}
disconnect(close?: any) {
return this.ioSocket.disconnect.apply(this.ioSocket, arguments);
}
emit(eventName: string, ...args: any[]) {
return this.ioSocket.emit.apply(this.ioSocket, arguments);
}
removeListener(eventName: string, callback?: Function) {
return this.ioSocket.removeListener.apply(this.ioSocket, arguments);
}
removeAllListeners(eventName?: string) {
return this.ioSocket.removeAllListeners.apply(this.ioSocket, arguments);
}
fromEvent<T>(eventName: string): Observable<T> {
if (!this.subscribersCounter[eventName]) {
this.subscribersCounter[eventName] = 0;
}
this.subscribersCounter[eventName]++;
if (!this.eventObservables$[eventName]) {
this.eventObservables$[eventName] = new Observable((observer: any) => {
const listener = (data: T) => {
observer.next(data);
};
this.ioSocket.on(eventName, listener);
return () => {
this.subscribersCounter[eventName]--;
if (this.subscribersCounter[eventName] === 0) {
this.ioSocket.removeListener(eventName, listener);
delete this.eventObservables$[eventName];
}
};
}).pipe(
share()
);
}
return this.eventObservables$[eventName];
}
fromOneTimeEvent<T>(eventName: string): Promise<T> {
return new Promise<T>(resolve => this.once(eventName, resolve));
}
}