Skip to content

Commit

Permalink
Prevent socket timeouts by sending keepalive messages.
Browse files Browse the repository at this point in the history
  • Loading branch information
aduros committed Nov 29, 2023
1 parent f7f078f commit 29ae46a
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 16 deletions.
17 changes: 14 additions & 3 deletions runtimes/web/src/netplay/peer-manager.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/** WebRTC signaling messages. */
type Message = WhoAmIRequestMessage | WhoAmIReplyMessage | OfferMessage | AnswerMessage | CandidateMessage | AbortMessage;
type Message = WhoAmIRequestMessage | WhoAmIReplyMessage | OfferMessage | AnswerMessage | CandidateMessage | AbortMessage | KeepaliveMessage;

/** Sent by a newly connecting client requesting its peer ID. */
type WhoAmIRequestMessage = {
Expand Down Expand Up @@ -31,16 +31,26 @@ type AbortMessage = {
type: "ABORT";
}

type KeepaliveMessage = {
type: "KEEPALIVE";
}

/**
* Connects to our websocket server for exchanging the signaling messages needed to establish WebRTC
* peer-to-peer connections.
*/
class SignalClient {
private socket?: WebSocket;
private readonly bufferedOutput: string[] = [];
private keepaliveInterval: number;

constructor (private onMessage: (source: string, message: Message) => void) {
this.connect();

// Regularly send messages to keep the websocket connection from an idle timeout
this.keepaliveInterval = window.setInterval(() => {
this.send("", { type: "KEEPALIVE" }, false);
}, 15000);
}

private async connect (): Promise<void> {
Expand Down Expand Up @@ -81,18 +91,19 @@ class SignalClient {
this.bufferedOutput.length = 0;
}

send (target: string, message: Message) {
send (target: string, message: Message, deferIfNotReady = true) {
// console.log(`Sent ${message.type} message to ${target}`);
const output = JSON.stringify({ target, message });
if (this.socket?.readyState == 1) {
this.socket.send(output);
} else {
} else if (deferIfNotReady) {
this.bufferedOutput.push(output);
}
}

close () {
this.socket?.close();
window.clearInterval(this.keepaliveInterval);
}
}

Expand Down
32 changes: 19 additions & 13 deletions runtimes/web/webrtc-signal-server/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,26 @@ export const handler: APIGatewayProxyWebsocketHandlerV2 = async ({ body, request
if (body) {
const { target, message } = JSON.parse(body);

if (message.type === "WHOAMI_REQUEST") {
await sendToPeer("server", requestContext.connectionId, {
type: "WHOAMI_REPLY",
yourPeerId: requestContext.connectionId,
});
} else {
try {
await sendToPeer(requestContext.connectionId, target, message);
} catch (error) {
// Peer not found, send an abort message
await sendToPeer(target, requestContext.connectionId, {
type: "ABORT",
switch (message.type) {
case "WHOAMI_REQUEST":
await sendToPeer("server", requestContext.connectionId, {
type: "WHOAMI_REPLY",
yourPeerId: requestContext.connectionId,
});
}
break;
case "KEEPALIVE":
// Ignore this message, it only exists to keep the connection open
break;
default:
// Route the message to the given target
try {
await sendToPeer(requestContext.connectionId, target, message);
} catch (error) {
// Peer not found, send an abort message
await sendToPeer(target, requestContext.connectionId, {
type: "ABORT",
});
}
}
}

Expand Down

0 comments on commit 29ae46a

Please sign in to comment.