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