@hienlh/ppm 0.8.73 → 0.8.74
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/CHANGELOG.md +3 -2
- package/package.json +1 -1
- package/src/services/cloud-ws.service.ts +22 -15
package/CHANGELOG.md
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## [0.8.
|
|
3
|
+
## [0.8.74] - 2026-04-01
|
|
4
4
|
|
|
5
5
|
### Fixed
|
|
6
|
-
- **Cloud WS reconnect loop**: Stale WebSocket closure handlers from replaced connections no longer reset module state
|
|
6
|
+
- **Cloud WS reconnect loop**: Stale WebSocket closure handlers from replaced connections no longer reset module state
|
|
7
|
+
- **Cloud WS auth race**: Delay heartbeat/queue flush 500ms after auth to let server complete async DB auth — prevents 4002 rejection
|
|
7
8
|
|
|
8
9
|
## [0.8.72] - 2026-03-31
|
|
9
10
|
|
package/package.json
CHANGED
|
@@ -140,8 +140,10 @@ function doConnect(): void {
|
|
|
140
140
|
sock.onopen = () => {
|
|
141
141
|
if (ws !== sock) return; // stale — newer connection replaced us
|
|
142
142
|
reconnecting = false;
|
|
143
|
+
reconnectAttempt = 0;
|
|
143
144
|
log("INFO", "Cloud WS connected, sending auth");
|
|
144
145
|
|
|
146
|
+
// Send auth as first message — server must process this before any other msg
|
|
145
147
|
sock.send(JSON.stringify({
|
|
146
148
|
type: "auth",
|
|
147
149
|
deviceId,
|
|
@@ -150,23 +152,28 @@ function doConnect(): void {
|
|
|
150
152
|
version: 1,
|
|
151
153
|
}));
|
|
152
154
|
|
|
153
|
-
connected
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
155
|
+
// Delay setting connected + sending heartbeat to let server process auth.
|
|
156
|
+
// Server's authenticateDevice() is async (DB lookup), so messages sent
|
|
157
|
+
// immediately after auth arrive before authenticated=true → 4002 reject.
|
|
158
|
+
setTimeout(() => {
|
|
159
|
+
if (ws !== sock) return; // replaced during delay
|
|
160
|
+
connected = true;
|
|
161
|
+
|
|
162
|
+
// Flush queued messages
|
|
163
|
+
while (outboundQueue.length > 0 && connected) {
|
|
164
|
+
const msg = outboundQueue.shift()!;
|
|
165
|
+
sock.send(JSON.stringify(msg));
|
|
166
|
+
}
|
|
161
167
|
|
|
162
|
-
|
|
163
|
-
|
|
168
|
+
// Send immediate heartbeat
|
|
169
|
+
if (getHeartbeatData) send(getHeartbeatData());
|
|
164
170
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
171
|
+
// Start periodic heartbeat
|
|
172
|
+
if (heartbeatTimer) clearInterval(heartbeatTimer);
|
|
173
|
+
heartbeatTimer = setInterval(() => {
|
|
174
|
+
if (getHeartbeatData && connected) send(getHeartbeatData());
|
|
175
|
+
}, HEARTBEAT_INTERVAL_MS);
|
|
176
|
+
}, 500); // 500ms for DB auth round-trip
|
|
170
177
|
};
|
|
171
178
|
|
|
172
179
|
sock.onmessage = (event) => {
|