Skip to content

Instantly share code, notes, and snippets.

@vitkon
Created April 28, 2017 00:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vitkon/ca1367c24210a0760643212d2ac8a377 to your computer and use it in GitHub Desktop.
Save vitkon/ca1367c24210a0760643212d2ac8a377 to your computer and use it in GitHub Desktop.
WebSocket Provider (sockjs + stomp)
const wsUri = 'http://localhost:8080/websocket';
const webstomp = require('webstomp-client');
const SockJS = require('sockjs-client');
const TIMEOUT = 5000;
export enum SocketStatus {
CLOSED,
CONNECTING,
CONNECTED,
ERROR,
}
export default class WebSocketProvider {
private static instance: WebSocketProvider;
private socket: any;
private status: SocketStatus;
private client: any = {};
private subscriptions: any = {};
private timer: any;
public connect(headers = {}): Promise<any> {
return new Promise((resolve, reject) => {
if (this.status === SocketStatus.CONNECTED) {
resolve();
}
if (this.status === SocketStatus.CLOSED) {
this.status = SocketStatus.CONNECTING;
this.client.connect(
headers,
() => this.onConnect(resolve),
() => this.onError(reject)
);
}
if (this.status === SocketStatus.CONNECTING) {
this.reconnect();
}
});
}
public send(topic: string, body: any = '', headers: any = {}): void {
const message = JSON.stringify(body);
this.client.send(topic, headers, message);
}
public disconnect(headers = {}): Promise<any> {
return new Promise((resolve) => {
this.client.disconnect(() => this.onDisconnect(resolve), headers);
});
}
public subscribe(topic: string, callback: () => any, headers: any = {}) {
if (this.status === SocketStatus.CONNECTED) {
const subscription = this.client.subscribe(topic, callback, headers);
this.client.subscriptions[topic] = subscription;
return subscription;
} else {
setTimeout(() => this.subscribe(topic, callback, headers), TIMEOUT);
}
}
public unsubscribe(topic: string) {
const subscription = this.getSubscriptionByTopic(topic);
if (subscription) {
subscription.unsubscribe();
}
}
private onConnect(resolve: () => any): void {
this.status = SocketStatus.CONNECTED
resolve();
}
private onError(reject: () => any): void {
this.status = SocketStatus.ERROR;
reject();
}
private onDisconnect(resolve: () => any) {
this.status = SocketStatus.CLOSED;
resolve();
}
private reconnect() {
this.timer = setTimeout(() => this.connect, TIMEOUT);
}
private getSubscriptionByTopic(topic: string) {
return this.client.subscriptions[topic];
}
private setupSocket(uri: string, protocols: string[] = []) {
this.status = SocketStatus.CLOSED;
this.socket = new SockJS(uri);
this.client = webstomp.over(this.socket);
this.socket.onclose = () => this.reconnect();
}
private constructor(uri: string, protocols: string[] = []) {
this.setupSocket(uri, protocols);
this.connect();
}
static get Instance() {
if (this.instance === null || this.instance === undefined) {
this.instance = new WebSocketProvider(wsUri);
}
return this.instance;
}
}
const u = () => WebSocketProvider.Instance.unsubscribe('/topic/CURRENCY.GBP.USD');
const w = WebSocketProvider.Instance;
// WebSocketProvider.Instance.subscribe(
// '/topic/CURRENCY.GBP.USD', () => {}
// );
WebSocketProvider.Instance.subscribe(
'/topic/CURRENCY.GBP.USD', () => { u() }
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment