summaryrefslogtreecommitdiff
path: root/ext/websocket/01_websocket.js
diff options
context:
space:
mode:
authorLeo Kettmeir <crowlkats@toaxl.com>2022-01-06 17:41:16 +0100
committerGitHub <noreply@github.com>2022-01-06 17:41:16 +0100
commit2067820714fea49be1692fa678754488ace8228b (patch)
tree2decf412d953016a5b4853e77b04f94466a588dc /ext/websocket/01_websocket.js
parent46f2ff120587cd1cb7b11e66d41ad6ad46fb09a8 (diff)
feat(ext/websocket): server automatically handle ping/pong for incoming WebSocket (#13172)
Diffstat (limited to 'ext/websocket/01_websocket.js')
-rw-r--r--ext/websocket/01_websocket.js48
1 files changed, 48 insertions, 0 deletions
diff --git a/ext/websocket/01_websocket.js b/ext/websocket/01_websocket.js
index e11a2c55f..46cb58441 100644
--- a/ext/websocket/01_websocket.js
+++ b/ext/websocket/01_websocket.js
@@ -69,7 +69,11 @@
const _binaryType = Symbol("[[binaryType]]");
const _bufferedAmount = Symbol("[[bufferedAmount]]");
const _eventLoop = Symbol("[[eventLoop]]");
+
const _server = Symbol("[[server]]");
+ const _idleTimeoutDuration = Symbol("[[idleTimeout]]");
+ const _idleTimeoutTimeout = Symbol("[[idleTimeoutTimeout]]");
+ const _serverHandleIdleTimeout = Symbol("[[serverHandleIdleTimeout]]");
class WebSocket extends EventTarget {
[_rid];
@@ -388,6 +392,7 @@
switch (kind) {
case "string": {
+ this[_serverHandleIdleTimeout]();
const event = new MessageEvent("message", {
data: value,
origin: this[_url],
@@ -396,6 +401,7 @@
break;
}
case "binary": {
+ this[_serverHandleIdleTimeout]();
let data;
if (this.binaryType === "blob") {
@@ -417,9 +423,14 @@
});
break;
}
+ case "pong": {
+ this[_serverHandleIdleTimeout]();
+ break;
+ }
case "closed":
case "close": {
this[_readyState] = CLOSED;
+ clearTimeout(this[_idleTimeoutTimeout]);
const event = new CloseEvent("close", {
wasClean: true,
@@ -446,6 +457,40 @@
}
}
}
+
+ [_serverHandleIdleTimeout]() {
+ if (this[_idleTimeoutDuration]) {
+ clearTimeout(this[_idleTimeoutTimeout]);
+ this[_idleTimeoutTimeout] = setTimeout(async () => {
+ await core.opAsync("op_ws_send", this[_rid], {
+ kind: "ping",
+ });
+ this[_idleTimeoutTimeout] = setTimeout(async () => {
+ this[_readyState] = CLOSING;
+ const reason = "No response from ping frame.";
+ await core.opAsync("op_ws_close", {
+ rid: this[_rid],
+ code: 1001,
+ reason,
+ });
+ this[_readyState] = CLOSED;
+
+ const errEvent = new ErrorEvent("error", {
+ message: reason,
+ });
+ this.dispatchEvent(errEvent);
+
+ const event = new CloseEvent("close", {
+ wasClean: false,
+ code: 1001,
+ reason,
+ });
+ this.dispatchEvent(event);
+ core.tryClose(this[_rid]);
+ }, (this[_idleTimeoutDuration] / 2) * 1000);
+ }, (this[_idleTimeoutDuration] / 2) * 1000);
+ }
+ }
}
ObjectDefineProperties(WebSocket, {
@@ -477,5 +522,8 @@
_eventLoop,
_protocol,
_server,
+ _idleTimeoutDuration,
+ _idleTimeoutTimeout,
+ _serverHandleIdleTimeout,
};
})(this);