Backed out changeset 70210dd7915c (bug 1926722) for causing LeakSanitizer failures...
[gecko.git] / remote / server / WebSocketTransport.sys.mjs
blob0ac6a6399a5312cebef6a70b214bca85fe231642
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 // This is an XPCOM service-ified copy of ../devtools/shared/transport/websocket-transport.js.
7 const lazy = {};
9 ChromeUtils.defineESModuleGetters(lazy, {
10   EventEmitter: "resource://gre/modules/EventEmitter.sys.mjs",
11 });
13 export function WebSocketTransport(socket) {
14   lazy.EventEmitter.decorate(this);
16   this.active = false;
17   this.hooks = null;
18   this.socket = socket;
21 WebSocketTransport.prototype = {
22   ready() {
23     if (this.active) {
24       return;
25     }
27     this.socket.addEventListener("message", this);
28     this.socket.addEventListener("close", this);
30     this.active = true;
31   },
33   send(object) {
34     this.emit("send", object);
35     if (this.socket) {
36       this.socket.send(JSON.stringify(object));
37     }
38   },
40   startBulkSend() {
41     throw new Error("Bulk send is not supported by WebSocket transport");
42   },
44   /**
45    * Force closing the active connection and WebSocket.
46    */
47   close() {
48     if (!this.socket) {
49       return;
50     }
51     this.emit("close");
53     if (this.hooks) {
54       this.hooks.onConnectionClose();
55     }
57     this.active = false;
59     this.socket.removeEventListener("message", this);
61     // Remove the listener that is used when the connection
62     // is closed because we already emitted the 'close' event.
63     // Instead listen for the closing of the WebSocket.
64     this.socket.removeEventListener("close", this);
65     this.socket.addEventListener("close", this.onSocketClose.bind(this));
67     // Close socket with code `1000` for a normal closure.
68     this.socket.close(1000);
69   },
71   /**
72    * Callback for socket on close event,
73    * it is used in case websocket was closed by the client.
74    */
75   onClose() {
76     if (!this.socket) {
77       return;
78     }
79     this.emit("close");
81     if (this.hooks) {
82       this.hooks.onConnectionClose();
83       this.hooks.onSocketClose();
84       this.hooks = null;
85     }
87     this.active = false;
89     this.socket.removeEventListener("message", this);
90     this.socket.removeEventListener("close", this);
91     this.socket = null;
92   },
94   /**
95    * Callback which is called when we can be sure that websocket is closed.
96    */
97   onSocketClose() {
98     this.socket = null;
100     if (this.hooks) {
101       this.hooks.onSocketClose();
102       this.hooks = null;
103     }
104   },
106   handleEvent(event) {
107     switch (event.type) {
108       case "message":
109         this.onMessage(event);
110         break;
111       case "close":
112         this.onClose();
113         break;
114     }
115   },
117   onMessage({ data }) {
118     if (typeof data !== "string") {
119       throw new Error(
120         "Binary messages are not supported by WebSocket transport"
121       );
122     }
124     const object = JSON.parse(data);
125     this.emit("packet", object);
126     if (this.hooks) {
127       this.hooks.onPacket(object);
128     }
129   },