openclaw-seatalk 0.3.1 → 0.3.2

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openclaw-seatalk",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "description": "OpenClaw SeaTalk channel plugin",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -14,6 +14,7 @@ import type { ResolvedSeaTalkAccount, SeaTalkCallbackRequest } from "./types.js"
14
14
  const INITIAL_BACKOFF_MS = 1_000;
15
15
  const MAX_BACKOFF_MS = 30_000;
16
16
  const BACKOFF_MULTIPLIER = 2;
17
+ const STALE_TIMEOUT_MS = 75_000;
17
18
 
18
19
  function sleep(ms: number, signal?: AbortSignal): Promise<void> {
19
20
  return new Promise((resolve) => {
@@ -64,13 +65,36 @@ async function connectSingleAccount(params: {
64
65
  log(`seatalk[${accountId}]: connecting to relay ${relayUrl}...`);
65
66
  const ws = new WebSocket(relayUrl);
66
67
 
68
+ let staleTimer: ReturnType<typeof setTimeout> | undefined;
69
+ const clearStaleTimer = () => {
70
+ if (staleTimer) {
71
+ clearTimeout(staleTimer);
72
+ staleTimer = undefined;
73
+ }
74
+ };
75
+ const armStaleTimer = () => {
76
+ clearStaleTimer();
77
+ staleTimer = setTimeout(() => {
78
+ error(
79
+ `seatalk[${accountId}]: relay silent for ${STALE_TIMEOUT_MS}ms, terminating`,
80
+ );
81
+ ws.terminate();
82
+ }, STALE_TIMEOUT_MS);
83
+ };
84
+
67
85
  const handleAbort = () => {
86
+ clearStaleTimer();
68
87
  ws.close();
69
88
  resolve();
70
89
  };
71
90
  abortSignal?.addEventListener("abort", handleAbort, { once: true });
72
91
 
92
+ ws.on("upgrade", (response) => {
93
+ response.socket.setKeepAlive(true, 60_000);
94
+ });
95
+
73
96
  ws.on("open", () => {
97
+ armStaleTimer();
74
98
  log(`seatalk[${accountId}]: relay connected, authenticating...`);
75
99
  ws.send(
76
100
  JSON.stringify({
@@ -85,6 +109,7 @@ async function connectSingleAccount(params: {
85
109
  let authenticated = false;
86
110
 
87
111
  ws.on("message", (raw) => {
112
+ armStaleTimer();
88
113
  let msg: { type: string; event?: SeaTalkCallbackRequest; error?: string };
89
114
  try {
90
115
  msg = JSON.parse(String(raw));
@@ -132,6 +157,7 @@ async function connectSingleAccount(params: {
132
157
  });
133
158
 
134
159
  ws.on("close", (code, reason) => {
160
+ clearStaleTimer();
135
161
  abortSignal?.removeEventListener("abort", handleAbort);
136
162
  if (authenticated) {
137
163
  log(
@@ -142,6 +168,7 @@ async function connectSingleAccount(params: {
142
168
  });
143
169
 
144
170
  ws.on("error", (err) => {
171
+ clearStaleTimer();
145
172
  abortSignal?.removeEventListener("abort", handleAbort);
146
173
  error(`seatalk[${accountId}]: relay connection error: ${String(err)}`);
147
174
  resolve();