fix: 按 K-00 约定修复 JS SDK 断线重交与退避

This commit is contained in:
Nixevol
2026-09-30 16:24:13 +08:00
parent f6f8ccf269
commit 55aa0ccf53
10 changed files with 1049 additions and 184 deletions
+27 -4
View File
@@ -11,9 +11,11 @@ export interface FakeConnect {
cleanStart: boolean;
sessionExpiry: number;
password: string;
receiveMaximumSet: boolean;
keepalive: number;
}
/** 单测用假 MQTT。 */
/** 单测用假 MQTT,不从包入口导出。 */
export class FakeTransport implements Transport {
private cfg?: TransportConfig;
private cred = "";
@@ -25,6 +27,7 @@ export class FakeTransport implements Transport {
maxBodyBytes = 262144;
maxMetaBytes = 4096;
maxFrameBytes = 786432;
publishUpImpl?: (payload: string) => Promise<void>;
setCredential(passwordOrToken: string): void {
this.cred = passwordOrToken;
@@ -32,11 +35,16 @@ export class FakeTransport implements Transport {
async start(cfg: TransportConfig): Promise<void> {
this.cfg = cfg;
await this.simulateConnectOK();
queueMicrotask(() => {
void this.simulateConnectOK().catch(() => {});
});
}
async publishUp(payload: Uint8Array | string): Promise<void> {
const s = typeof payload === "string" ? payload : new TextDecoder().decode(payload);
if (this.publishUpImpl) {
await this.publishUpImpl(s);
}
this.up.push(s);
if (this.autoHello) {
try {
@@ -49,7 +57,7 @@ export class FakeTransport implements Transport {
}
async stop(): Promise<void> {
this.cfg?.onOffline();
/* 不触发 onOffline,避免 close 后误重连 */
}
private replyHello(rid: string): void {
@@ -75,7 +83,13 @@ export class FakeTransport implements Transport {
async simulateConnectOK(): Promise<void> {
const { cleanStart, sessionExpiry } = buildCleanConnectFlags();
this.connects.push({ cleanStart, sessionExpiry, password: this.cred });
this.connects.push({
cleanStart,
sessionExpiry,
password: this.cred,
receiveMaximumSet: false,
keepalive: 30,
});
this.cfg?.onConnectPacket?.(cleanStart, sessionExpiry);
this.cfg?.backoff.markOnline();
await this.cfg?.mqttReady();
@@ -95,6 +109,15 @@ export class FakeTransport implements Transport {
this.cfg?.onKicked();
}
simulateServerDisconnect(code: number): void {
if (code === 0x8e) {
this.cfg?.onKicked();
return;
}
this.cfg?.backoff.markOffline();
this.cfg?.onOffline();
}
injectDown(payload: string | Uint8Array): void {
const bytes = typeof payload === "string" ? new TextEncoder().encode(payload) : payload;
this.cfg?.onDown(bytes);