Skip to content

Commit

Permalink
Extend WebSocket to include sendAsync
Browse files Browse the repository at this point in the history
  • Loading branch information
ArchangelWTF committed Dec 30, 2024
1 parent 694d0a8 commit 47b8eec
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 32 deletions.
18 changes: 3 additions & 15 deletions project/src/servers/WebSocketServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { JsonUtil } from "@spt/utils/JsonUtil";
import { RandomUtil } from "@spt/utils/RandomUtil";
import { inject, injectAll, injectable } from "tsyringe";
import WebSocket, { WebSocketServer as Server } from "ws";
import { SPTWebSocket } from "./ws/SPTWebsocket";

@injectable()
export class WebSocketServer {
Expand Down Expand Up @@ -52,12 +53,12 @@ export class WebSocketServer {
: this.localisationService.getText("server_start_success");
}

protected async wsOnConnection(ws: WebSocket, req: IncomingMessage): Promise<void> {
protected async wsOnConnection(ws: SPTWebSocket, req: IncomingMessage): Promise<void> {
const socketHandlers = this.webSocketConnectionHandlers.filter((wsh) => req.url.includes(wsh.getHookUrl()));
if ((socketHandlers?.length ?? 0) === 0) {
const message = `Socket connection received for url ${req.url}, but there is not websocket handler configured for it`;
this.logger.warning(message);
await this.sendAsync(ws, this.jsonUtil.serialize({ error: message }));
await ws.sendAsync(ws, this.jsonUtil.serialize({ error: message }));
ws.close();
return;
}
Expand All @@ -67,17 +68,4 @@ export class WebSocketServer {
this.logger.info(`WebSocketHandler "${wsh.getSocketId()}" connected`);
}
}

// biome-ignore lint/suspicious/noExplicitAny: Any is required here, I dont see any other way considering it will complain if we use BufferLike
protected sendAsync(ws: WebSocket, data: any): Promise<void> {
return new Promise((resolve, reject) => {
ws.send(data, (error) => {
if (error) {
reject(error);
} else {
resolve();
}
});
});
}
}
16 changes: 16 additions & 0 deletions project/src/servers/ws/SPTWebsocket.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import WebSocket from "ws";

class SPTWebSocket extends WebSocket {
// biome-ignore lint/suspicious/noExplicitAny: Any is required here, I dont see any other way considering it will complain if we use BufferLike
public sendAsync(ws: WebSocket, data: any): Promise<void> {
return new Promise((resolve, reject) => {
ws.send(data, (error) => {
if (error) {
reject(error);
} else {
resolve();
}
});
});
}
}
23 changes: 6 additions & 17 deletions project/src/servers/ws/SptWebSocketConnectionHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@ import { LocalisationService } from "@spt/services/LocalisationService";
import { JsonUtil } from "@spt/utils/JsonUtil";
import { inject, injectAll, injectable } from "tsyringe";
import { WebSocket } from "ws";
import { WebSocketServer } from "../WebSocketServer";
import { SPTWebSocket } from "./SPTWebsocket";

@injectable()
export class SptWebSocketConnectionHandler implements IWebSocketConnectionHandler {
protected httpConfig: IHttpConfig;
protected webSockets: Map<string, WebSocket> = new Map<string, WebSocket>();
protected webSockets: Map<string, SPTWebSocket> = new Map<string, SPTWebSocket>();
protected defaultNotification: IWsNotificationEvent = { type: NotificationEventType.PING, eventId: "ping" };

protected websocketPingHandler: NodeJS.Timeout | undefined;
Expand All @@ -39,7 +41,7 @@ export class SptWebSocketConnectionHandler implements IWebSocketConnectionHandle
return "/notifierServer/getwebsocket/";
}

public async onConnection(ws: WebSocket, req: IncomingMessage): Promise<void> {
public async onConnection(ws: SPTWebSocket, req: IncomingMessage): Promise<void> {
// Strip request and break it into sections
const splitUrl = req.url.substring(0, req.url.indexOf("?")).split("/");
const sessionID = splitUrl.pop();
Expand Down Expand Up @@ -67,7 +69,7 @@ export class SptWebSocketConnectionHandler implements IWebSocketConnectionHandle
this.logger.debug(this.localisationService.getText("websocket-pinging_player", sessionID));

if (ws.readyState === WebSocket.OPEN) {
await this.sendAsync(ws, this.jsonUtil.serialize(this.defaultNotification));
await ws.sendAsync(ws, this.jsonUtil.serialize(this.defaultNotification));
} else {
this.logger.debug(this.localisationService.getText("websocket-socket_lost_deleting_handle"));
clearInterval(this.websocketPingHandler);
Expand All @@ -81,7 +83,7 @@ export class SptWebSocketConnectionHandler implements IWebSocketConnectionHandle
if (this.isConnectionWebSocket(sessionID)) {
const ws = this.webSockets.get(sessionID);

await this.sendAsync(this.webSockets.get(sessionID), this.jsonUtil.serialize(output));
await ws.sendAsync(this.webSockets.get(sessionID), this.jsonUtil.serialize(output));
this.logger.debug(this.localisationService.getText("websocket-message_sent"));
} else {
this.logger.debug(this.localisationService.getText("websocket-not_ready_message_not_sent", sessionID));
Expand All @@ -98,17 +100,4 @@ export class SptWebSocketConnectionHandler implements IWebSocketConnectionHandle
public getSessionWebSocket(sessionID: string): WebSocket {
return this.webSockets[sessionID];
}

// biome-ignore lint/suspicious/noExplicitAny: Any is required here, I dont see any other way considering it will complain if we use BufferLike
public sendAsync(ws: WebSocket, data: any): Promise<void> {
return new Promise((resolve, reject) => {
ws.send(data, (error) => {
if (error) {
reject(error);
} else {
resolve();
}
});
});
}
}

0 comments on commit 47b8eec

Please sign in to comment.