-
Notifications
You must be signed in to change notification settings - Fork 5.9k
Closed
Description
Hi!
I have this Server class that I had to add these 3 properties to:
export class Server {
protected listener?: Deno.Listener;
protected numberOfConnections = 0;
protected closingPromise: Promise<void>;
protected closingPromiseResolver?: (value: void | PromiseLike<void>) => void;
// ...
public constructor(port: number = 4000) {
// ...
this.closingPromise = new Promise((resolve) => {
this.closingPromiseResolver = resolve;
});
// ...
}
private handleSocketOpen(_socket: WebSocket) {
logger.debug(`Server#handleSocketOpen`);
this.numberOfConnections++;
}
private handleSocketClose(_socket: WebSocket) {
logger.debug(`Server#handleSocketClose`);
this.numberOfConnections--;
if (this.closingPromiseResolver && this.numberOfConnections === 0) {
this.closingPromiseResolver();
}
}
private async handleConnections() {
logger.debug(`Server#handleConnections`);
if (!this.isRunning || !this.listener) {
throw new Error("not running");
}
let event: Maybe<Deno.RequestEvent> = null;
while (this.isRunning) {
try {
const connection = Deno.serveHttp(await this.listener.accept());
event = await connection.nextRequest();
} catch {
break;
}
if (event === null) {
break;
}
const { socket, response } = Deno.upgradeWebSocket(event.request);
socket.onopen = () => this.handleSocketOpen(socket);
socket.onmessage = (e) => this.handleSocketMessage(socket, e.data);
socket.onclose = () => this.handleSocketClose(socket);
socket.onerror = (e) => this.handleSocketError(socket, e);
event.respondWith(response);
}
logger.debug(`Server#handleConnections:done`);
}
public async untilAllSocketsClosed() {
if (this.numberOfConnections === 0) {
return;
}
await this.closingPromise;
}
public async start() {
logger.debug(`Server#start`);
this.listener = await Deno.listen({
port: this.port,
});
this.isRunning = true;
this.startedAt = new Date();
this.handleConnections();
this.closingPromise = new Promise((resolve) => {
this.closingPromiseResolver = resolve;
});
logger.debug(`Server#start:started`);
}
public async stop() {
logger.debug(`Server#stop`);
if (!this.isRunning || !this.listener) {
throw new Error("not running");
}
this.listener.close();
this.listener = undefined;
await this.untilAllSocketsClosed();
this.closingPromiseResolver = undefined;
this.isRunning = false;
this.startedAt = null;
logger.debug(`Server#stop:stop`);
}Is there a better way to wait until all sockets are closed?
I am running tests and each test creates a new server. If I close the server in one test with a sync op, the next test will try to spawn a new Deno.listen() on the same port and I will get an error.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels