@coclaw/openclaw-coclaw 0.2.2 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/realtime-bridge.js +27 -2
package/package.json
CHANGED
package/src/realtime-bridge.js
CHANGED
|
@@ -10,6 +10,7 @@ const RECONNECT_MS = 10_000;
|
|
|
10
10
|
const CONNECT_TIMEOUT_MS = 10_000;
|
|
11
11
|
const SERVER_HB_PING_MS = 25_000;
|
|
12
12
|
const SERVER_HB_TIMEOUT_MS = 45_000;
|
|
13
|
+
const SERVER_HB_MAX_MISS = 4; // 连续 4 次无响应才断连(~3 分钟)
|
|
13
14
|
|
|
14
15
|
function toServerWsUrl(baseUrl, token) {
|
|
15
16
|
const url = new URL(baseUrl);
|
|
@@ -88,6 +89,7 @@ export class RealtimeBridge {
|
|
|
88
89
|
this.intentionallyClosed = false;
|
|
89
90
|
this.serverHbInterval = null;
|
|
90
91
|
this.serverHbTimer = null;
|
|
92
|
+
this.__serverHbMissCount = 0;
|
|
91
93
|
}
|
|
92
94
|
|
|
93
95
|
__resolveWebSocket() {
|
|
@@ -102,6 +104,7 @@ export class RealtimeBridge {
|
|
|
102
104
|
|
|
103
105
|
__startServerHeartbeat(sock) {
|
|
104
106
|
this.__clearServerHeartbeat();
|
|
107
|
+
this.__serverHbMissCount = 0;
|
|
105
108
|
this.serverHbInterval = setInterval(() => {
|
|
106
109
|
if (sock.readyState === 1) {
|
|
107
110
|
try { sock.send(JSON.stringify({ type: 'ping' })); } catch {}
|
|
@@ -112,14 +115,36 @@ export class RealtimeBridge {
|
|
|
112
115
|
}
|
|
113
116
|
|
|
114
117
|
__resetServerHbTimeout(sock) {
|
|
118
|
+
this.__serverHbMissCount = 0;
|
|
115
119
|
if (this.serverHbTimer) clearTimeout(this.serverHbTimer);
|
|
116
120
|
this.serverHbTimer = setTimeout(() => {
|
|
117
|
-
this.
|
|
118
|
-
try { sock.close(4000, 'heartbeat_timeout'); } catch {}
|
|
121
|
+
this.__onServerHbMiss(sock);
|
|
119
122
|
}, SERVER_HB_TIMEOUT_MS);
|
|
120
123
|
this.serverHbTimer.unref?.();
|
|
121
124
|
}
|
|
122
125
|
|
|
126
|
+
__onServerHbMiss(sock) {
|
|
127
|
+
this.__serverHbMissCount++;
|
|
128
|
+
if (this.__serverHbMissCount < SERVER_HB_MAX_MISS) {
|
|
129
|
+
this.__logDebug(
|
|
130
|
+
`server heartbeat miss ${this.__serverHbMissCount}/${SERVER_HB_MAX_MISS}, will retry`
|
|
131
|
+
);
|
|
132
|
+
// 补发 ping,继续等下一轮
|
|
133
|
+
if (sock.readyState === 1) {
|
|
134
|
+
try { sock.send(JSON.stringify({ type: 'ping' })); } catch {}
|
|
135
|
+
}
|
|
136
|
+
this.serverHbTimer = setTimeout(() => {
|
|
137
|
+
this.__onServerHbMiss(sock);
|
|
138
|
+
}, SERVER_HB_TIMEOUT_MS);
|
|
139
|
+
this.serverHbTimer.unref?.();
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
this.logger.warn?.(
|
|
143
|
+
`[coclaw] server ws heartbeat timeout after ${this.__serverHbMissCount} consecutive misses (~${this.__serverHbMissCount * SERVER_HB_TIMEOUT_MS / 1000}s), closing`
|
|
144
|
+
);
|
|
145
|
+
try { sock.close(4000, 'heartbeat_timeout'); } catch {}
|
|
146
|
+
}
|
|
147
|
+
|
|
123
148
|
__clearServerHeartbeat() {
|
|
124
149
|
if (this.serverHbInterval) { clearInterval(this.serverHbInterval); this.serverHbInterval = null; }
|
|
125
150
|
if (this.serverHbTimer) { clearTimeout(this.serverHbTimer); this.serverHbTimer = null; }
|