]> Untitled Git - lemmy-ui.git/blob - src/shared/services/WebSocketService.ts
85a1af85b83aa4413d100938b71fb614d8aed726
[lemmy-ui.git] / src / shared / services / WebSocketService.ts
1 import { PersonViewSafe, WebSocketJsonResponse } from "lemmy-js-client";
2 import { Observable } from "rxjs";
3 import { share } from "rxjs/operators";
4 import {
5   ExponentialBackoff,
6   Websocket as WS,
7   WebsocketBuilder,
8 } from "websocket-ts";
9 import { wsUri } from "../env";
10 import { isBrowser } from "../utils";
11
12 export class WebSocketService {
13   private static _instance: WebSocketService;
14   private ws: WS;
15   public subject: Observable<any>;
16
17   public admins: PersonViewSafe[];
18   public banned: PersonViewSafe[];
19
20   private constructor() {
21     let firstConnect = true;
22
23     this.subject = new Observable((obs: any) => {
24       this.ws = new WebsocketBuilder(wsUri)
25         .onMessage((_i, e) => {
26           try {
27             obs.next(JSON.parse(e.data.toString()));
28           } catch (err) {
29             console.log(err);
30           }
31         })
32         .onOpen(() => {
33           console.log(`Connected to ${wsUri}`);
34
35           if (!firstConnect) {
36             let res: WebSocketJsonResponse<any> = {
37               reconnect: true,
38             };
39             obs.next(res);
40           }
41           firstConnect = false;
42         })
43         .onRetry(() => {
44           console.log("Retrying websocket connection...");
45         })
46         .onClose(() => {
47           console.error("Websocket closed.");
48         })
49         .withBackoff(new ExponentialBackoff(100, 7))
50         .build();
51     }).pipe(share());
52
53     if (isBrowser()) {
54       window.onunload = () => {
55         this.ws.close();
56
57         // Clears out scroll positions.
58         sessionStorage.clear();
59       };
60     }
61   }
62
63   public send(data: string) {
64     this.ws.send(data);
65   }
66
67   public static get Instance() {
68     return this._instance || (this._instance = new this());
69   }
70 }