Skip to content

Commit c6feceb

Browse files
committed
feat: WebSocketServer now extends EventTarget with connection, start and stop events
[ci skip]
1 parent f260d73 commit c6feceb

2 files changed

Lines changed: 93 additions & 14 deletions

File tree

src/websockets/WebSocketServer.ts

Lines changed: 47 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import Logger from '@matrixai/logger';
2020
import uWebsocket from 'uWebSockets.js';
2121
import WebSocketStream from './WebSocketStream';
2222
import * as clientRPCErrors from './errors';
23+
import * as webSocketEvents from './events';
2324
import { promise } from '../utils';
2425

2526
type ConnectionCallback = (
@@ -39,9 +40,15 @@ type Context = {
3940
logger: Logger;
4041
};
4142

43+
/**
44+
* Events:
45+
* - start
46+
* - stop
47+
* - connection
48+
*/
4249
interface WebSocketServer extends startStop.StartStop {}
4350
@startStop.StartStop()
44-
class WebSocketServer {
51+
class WebSocketServer extends EventTarget {
4552
static async createWebSocketServer({
4653
connectionCallback,
4754
tlsConfig,
@@ -90,7 +97,9 @@ class WebSocketServer {
9097
protected server: uWebsocket.TemplatedApp;
9198
protected listenSocket: uWebsocket.us_listen_socket;
9299
protected host: string;
93-
protected connectionCallback: ConnectionCallback;
100+
protected connectionEventHandler: (
101+
event: webSocketEvents.ConnectionEvent,
102+
) => void;
94103
protected activeSockets: Set<WebSocketStream> = new Set();
95104
protected connectionIndex: number = 0;
96105

@@ -110,23 +119,35 @@ class WebSocketServer {
110119
protected idleTimeout: number | undefined,
111120
protected pingInterval: number,
112121
protected pingTimeout: number,
113-
) {}
122+
) {
123+
super();
124+
}
114125

115126
public async start({
116-
connectionCallback,
117127
tlsConfig,
118128
basePath = os.tmpdir(),
119129
host,
120130
port = 0,
131+
connectionCallback,
121132
}: {
122-
connectionCallback: ConnectionCallback;
123133
tlsConfig: TLSConfig;
124134
basePath?: string;
125135
host?: string;
126136
port?: number;
137+
connectionCallback?: ConnectionCallback;
127138
}): Promise<void> {
128139
this.logger.info(`Starting ${this.constructor.name}`);
129-
this.connectionCallback = connectionCallback;
140+
if (connectionCallback != null) {
141+
this.connectionEventHandler = (
142+
event: webSocketEvents.ConnectionEvent,
143+
) => {
144+
connectionCallback(
145+
event.detail.webSocketStream,
146+
event.detail.connectionInfo,
147+
);
148+
};
149+
this.addEventListener('connection', this.connectionEventHandler);
150+
}
130151
await this.setupServer(basePath, tlsConfig);
131152
this.server.ws('/*', {
132153
sendPingsAutomatically: true,
@@ -169,6 +190,14 @@ class WebSocketServer {
169190
`Listening on port ${uWebsocket.us_socket_local_port(this.listenSocket)}`,
170191
);
171192
this.host = host ?? '127.0.0.1';
193+
this.dispatchEvent(
194+
new webSocketEvents.StartEvent({
195+
detail: {
196+
host: this.host,
197+
port: this.port,
198+
},
199+
}),
200+
);
172201
this.logger.info(`Started ${this.constructor.name}`);
173202
}
174203

@@ -186,6 +215,10 @@ class WebSocketServer {
186215
for (const webSocketStream of this.activeSockets) {
187216
webSocketStream.endedProm.catch(() => {}); // Ignore errors
188217
}
218+
if (this.connectionEventHandler != null) {
219+
this.removeEventListener('connection', this.connectionEventHandler);
220+
}
221+
this.dispatchEvent(new webSocketEvents.StopEvent());
189222
this.logger.info(`Stopped ${this.constructor.name}`);
190223
}
191224

@@ -265,14 +298,14 @@ class WebSocketServer {
265298
localHost: this.host,
266299
localPort: this.port,
267300
};
268-
const context = ws.getUserData();
269-
context.logger.debug('Calling callback');
270-
try {
271-
this.connectionCallback(webSocketStream, connectionInfo);
272-
} catch (e) {
273-
context.close(ws, 0, Buffer.from(''));
274-
context.logger.error(e.toString());
275-
}
301+
this.dispatchEvent(
302+
new webSocketEvents.ConnectionEvent({
303+
detail: {
304+
webSocketStream,
305+
connectionInfo,
306+
},
307+
}),
308+
);
276309
};
277310

278311
/**

src/websockets/events.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import type WebSocketStream from 'websockets/WebSocketStream';
2+
import type { ConnectionInfo } from 'RPC/types';
3+
4+
class StartEvent extends Event {
5+
public detail: {
6+
host: string;
7+
port: number;
8+
};
9+
constructor(
10+
options: EventInit & {
11+
detail: {
12+
host: string;
13+
port: number;
14+
};
15+
},
16+
) {
17+
super('start', options);
18+
this.detail = options.detail;
19+
}
20+
}
21+
22+
class StopEvent extends Event {
23+
constructor(options?: EventInit) {
24+
super('stop', options);
25+
}
26+
}
27+
28+
class ConnectionEvent extends Event {
29+
public detail: {
30+
webSocketStream: WebSocketStream;
31+
connectionInfo: ConnectionInfo;
32+
};
33+
constructor(
34+
options: EventInit & {
35+
detail: {
36+
webSocketStream: WebSocketStream;
37+
connectionInfo: ConnectionInfo;
38+
};
39+
},
40+
) {
41+
super('connection', options);
42+
this.detail = options.detail;
43+
}
44+
}
45+
46+
export { StartEvent, StopEvent, ConnectionEvent };

0 commit comments

Comments
 (0)