im-rtc-call-engine 1.0.0
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/LICENSE +21 -0
- package/dist/bytes.d.ts +11 -0
- package/dist/bytes.d.ts.map +1 -0
- package/dist/bytes.js +20 -0
- package/dist/bytes.js.map +1 -0
- package/dist/callOptions.d.ts +27 -0
- package/dist/callOptions.d.ts.map +1 -0
- package/dist/callOptions.js +19 -0
- package/dist/callOptions.js.map +1 -0
- package/dist/deviceId.d.ts +10 -0
- package/dist/deviceId.d.ts.map +1 -0
- package/dist/deviceId.js +55 -0
- package/dist/deviceId.js.map +1 -0
- package/dist/engine.d.ts +302 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +489 -0
- package/dist/engine.js.map +1 -0
- package/dist/engineBus.d.ts +16 -0
- package/dist/engineBus.d.ts.map +1 -0
- package/dist/engineBus.js +89 -0
- package/dist/engineBus.js.map +1 -0
- package/dist/engineWiring.d.ts +40 -0
- package/dist/engineWiring.d.ts.map +1 -0
- package/dist/engineWiring.js +57 -0
- package/dist/engineWiring.js.map +1 -0
- package/dist/errors.d.ts +185 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +253 -0
- package/dist/errors.js.map +1 -0
- package/dist/eventBus.d.ts +24 -0
- package/dist/eventBus.d.ts.map +1 -0
- package/dist/eventBus.js +50 -0
- package/dist/eventBus.js.map +1 -0
- package/dist/events.d.ts +220 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +35 -0
- package/dist/events.js.map +1 -0
- package/dist/frameLoop.d.ts +93 -0
- package/dist/frameLoop.d.ts.map +1 -0
- package/dist/frameLoop.js +346 -0
- package/dist/frameLoop.js.map +1 -0
- package/dist/index.d.ts +60 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +42 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +64 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +101 -0
- package/dist/logger.js.map +1 -0
- package/dist/media/engineMediaApi.d.ts +40 -0
- package/dist/media/engineMediaApi.d.ts.map +1 -0
- package/dist/media/engineMediaApi.js +71 -0
- package/dist/media/engineMediaApi.js.map +1 -0
- package/dist/media/firstFrameGate.d.ts +47 -0
- package/dist/media/firstFrameGate.d.ts.map +1 -0
- package/dist/media/firstFrameGate.js +117 -0
- package/dist/media/firstFrameGate.js.map +1 -0
- package/dist/media/mediaAdapter.d.ts +135 -0
- package/dist/media/mediaAdapter.d.ts.map +1 -0
- package/dist/media/mediaAdapter.js +2 -0
- package/dist/media/mediaAdapter.js.map +1 -0
- package/dist/media/mediaBridge.d.ts +99 -0
- package/dist/media/mediaBridge.d.ts.map +1 -0
- package/dist/media/mediaBridge.js +186 -0
- package/dist/media/mediaBridge.js.map +1 -0
- package/dist/media/mediaPlane.d.ts +58 -0
- package/dist/media/mediaPlane.d.ts.map +1 -0
- package/dist/media/mediaPlane.js +119 -0
- package/dist/media/mediaPlane.js.map +1 -0
- package/dist/media/videoProfile.d.ts +79 -0
- package/dist/media/videoProfile.d.ts.map +1 -0
- package/dist/media/videoProfile.js +46 -0
- package/dist/media/videoProfile.js.map +1 -0
- package/dist/media/videoProfile.test.d.ts +2 -0
- package/dist/media/videoProfile.test.d.ts.map +1 -0
- package/dist/media/videoProfile.test.js +26 -0
- package/dist/media/videoProfile.test.js.map +1 -0
- package/dist/media/viewRegistry.d.ts +75 -0
- package/dist/media/viewRegistry.d.ts.map +1 -0
- package/dist/media/viewRegistry.js +130 -0
- package/dist/media/viewRegistry.js.map +1 -0
- package/dist/media/webrtcAdapter.d.ts +158 -0
- package/dist/media/webrtcAdapter.d.ts.map +1 -0
- package/dist/media/webrtcAdapter.js +502 -0
- package/dist/media/webrtcAdapter.js.map +1 -0
- package/dist/protocolId.d.ts +14 -0
- package/dist/protocolId.d.ts.map +1 -0
- package/dist/protocolId.js +109 -0
- package/dist/protocolId.js.map +1 -0
- package/dist/reasons.d.ts +63 -0
- package/dist/reasons.d.ts.map +1 -0
- package/dist/reasons.js +81 -0
- package/dist/reasons.js.map +1 -0
- package/dist/redact.d.ts +19 -0
- package/dist/redact.d.ts.map +1 -0
- package/dist/redact.js +50 -0
- package/dist/redact.js.map +1 -0
- package/dist/signaling/backoff.d.ts +17 -0
- package/dist/signaling/backoff.d.ts.map +1 -0
- package/dist/signaling/backoff.js +23 -0
- package/dist/signaling/backoff.js.map +1 -0
- package/dist/signaling/candidate.d.ts +19 -0
- package/dist/signaling/candidate.d.ts.map +1 -0
- package/dist/signaling/candidate.js +22 -0
- package/dist/signaling/candidate.js.map +1 -0
- package/dist/signaling/caseMapping.d.ts +19 -0
- package/dist/signaling/caseMapping.d.ts.map +1 -0
- package/dist/signaling/caseMapping.js +34 -0
- package/dist/signaling/caseMapping.js.map +1 -0
- package/dist/signaling/connection.d.ts +110 -0
- package/dist/signaling/connection.d.ts.map +1 -0
- package/dist/signaling/connection.js +365 -0
- package/dist/signaling/connection.js.map +1 -0
- package/dist/signaling/connectionFactory.d.ts +55 -0
- package/dist/signaling/connectionFactory.d.ts.map +1 -0
- package/dist/signaling/connectionFactory.js +29 -0
- package/dist/signaling/connectionFactory.js.map +1 -0
- package/dist/signaling/connectionTypes.d.ts +94 -0
- package/dist/signaling/connectionTypes.d.ts.map +1 -0
- package/dist/signaling/connectionTypes.js +2 -0
- package/dist/signaling/connectionTypes.js.map +1 -0
- package/dist/signaling/discipline.d.ts +6 -0
- package/dist/signaling/discipline.d.ts.map +1 -0
- package/dist/signaling/discipline.js +100 -0
- package/dist/signaling/discipline.js.map +1 -0
- package/dist/signaling/enums.d.ts +53 -0
- package/dist/signaling/enums.d.ts.map +1 -0
- package/dist/signaling/enums.js +52 -0
- package/dist/signaling/enums.js.map +1 -0
- package/dist/signaling/envelope.d.ts +31 -0
- package/dist/signaling/envelope.d.ts.map +1 -0
- package/dist/signaling/envelope.js +91 -0
- package/dist/signaling/envelope.js.map +1 -0
- package/dist/signaling/fieldSpec.d.ts +101 -0
- package/dist/signaling/fieldSpec.d.ts.map +1 -0
- package/dist/signaling/fieldSpec.js +130 -0
- package/dist/signaling/fieldSpec.js.map +1 -0
- package/dist/signaling/frameSender.d.ts +34 -0
- package/dist/signaling/frameSender.d.ts.map +1 -0
- package/dist/signaling/frameSender.js +57 -0
- package/dist/signaling/frameSender.js.map +1 -0
- package/dist/signaling/frames.call.d.ts +299 -0
- package/dist/signaling/frames.call.d.ts.map +1 -0
- package/dist/signaling/frames.call.js +149 -0
- package/dist/signaling/frames.call.js.map +1 -0
- package/dist/signaling/frames.room.d.ts +566 -0
- package/dist/signaling/frames.room.d.ts.map +1 -0
- package/dist/signaling/frames.room.js +165 -0
- package/dist/signaling/frames.room.js.map +1 -0
- package/dist/signaling/frames.sys.d.ts +145 -0
- package/dist/signaling/frames.sys.d.ts.map +1 -0
- package/dist/signaling/frames.sys.js +53 -0
- package/dist/signaling/frames.sys.js.map +1 -0
- package/dist/signaling/handshakeGiveUp.d.ts +36 -0
- package/dist/signaling/handshakeGiveUp.d.ts.map +1 -0
- package/dist/signaling/handshakeGiveUp.js +48 -0
- package/dist/signaling/handshakeGiveUp.js.map +1 -0
- package/dist/signaling/heartbeat.d.ts +34 -0
- package/dist/signaling/heartbeat.d.ts.map +1 -0
- package/dist/signaling/heartbeat.js +52 -0
- package/dist/signaling/heartbeat.js.map +1 -0
- package/dist/signaling/pendingRequests.d.ts +33 -0
- package/dist/signaling/pendingRequests.d.ts.map +1 -0
- package/dist/signaling/pendingRequests.js +57 -0
- package/dist/signaling/pendingRequests.js.map +1 -0
- package/dist/signaling/reconnector.d.ts +43 -0
- package/dist/signaling/reconnector.d.ts.map +1 -0
- package/dist/signaling/reconnector.js +76 -0
- package/dist/signaling/reconnector.js.map +1 -0
- package/dist/signaling/registry.d.ts +100 -0
- package/dist/signaling/registry.d.ts.map +1 -0
- package/dist/signaling/registry.js +217 -0
- package/dist/signaling/registry.js.map +1 -0
- package/dist/signaling/resumeDeadline.d.ts +48 -0
- package/dist/signaling/resumeDeadline.d.ts.map +1 -0
- package/dist/signaling/resumeDeadline.js +89 -0
- package/dist/signaling/resumeDeadline.js.map +1 -0
- package/dist/signaling/tokenExpiry.d.ts +89 -0
- package/dist/signaling/tokenExpiry.d.ts.map +1 -0
- package/dist/signaling/tokenExpiry.js +106 -0
- package/dist/signaling/tokenExpiry.js.map +1 -0
- package/dist/signaling/webSocket.d.ts +59 -0
- package/dist/signaling/webSocket.d.ts.map +1 -0
- package/dist/signaling/webSocket.js +50 -0
- package/dist/signaling/webSocket.js.map +1 -0
- package/dist/state/callMachine.d.ts +56 -0
- package/dist/state/callMachine.d.ts.map +1 -0
- package/dist/state/callMachine.js +176 -0
- package/dist/state/callMachine.js.map +1 -0
- package/dist/state/callRecv.d.ts +12 -0
- package/dist/state/callRecv.d.ts.map +1 -0
- package/dist/state/callRecv.js +255 -0
- package/dist/state/callRecv.js.map +1 -0
- package/dist/state/engineMachine.d.ts +41 -0
- package/dist/state/engineMachine.d.ts.map +1 -0
- package/dist/state/engineMachine.js +210 -0
- package/dist/state/engineMachine.js.map +1 -0
- package/dist/state/forceEnd.d.ts +44 -0
- package/dist/state/forceEnd.d.ts.map +1 -0
- package/dist/state/forceEnd.js +96 -0
- package/dist/state/forceEnd.js.map +1 -0
- package/dist/state/roomMachine.d.ts +92 -0
- package/dist/state/roomMachine.d.ts.map +1 -0
- package/dist/state/roomMachine.js +319 -0
- package/dist/state/roomMachine.js.map +1 -0
- package/dist/state/roomRecv.d.ts +7 -0
- package/dist/state/roomRecv.d.ts.map +1 -0
- package/dist/state/roomRecv.js +209 -0
- package/dist/state/roomRecv.js.map +1 -0
- package/dist/state/types.d.ts +61 -0
- package/dist/state/types.d.ts.map +1 -0
- package/dist/state/types.js +30 -0
- package/dist/state/types.js.map +1 -0
- package/dist/version.d.ts +11 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +11 -0
- package/dist/version.js.map +1 -0
- package/package.json +35 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"callMachine.js","sourceRoot":"","sources":["../../src/state/callMachine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { CallContext } from './callMachine.js';
|
|
2
|
+
import type { MachineOutput } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* reduceRecv 处理一条下行帧。
|
|
5
|
+
*
|
|
6
|
+
* 两条优先级规则写在最前面,别挪:
|
|
7
|
+
* 1. **终态帧优先**——任何非 idle 状态收到 call.ended 都直达 idle(§5.1)。
|
|
8
|
+
* 2. **idle 下的迟到帧一律静默丢弃**:不抛回调、不发帧、不报错。
|
|
9
|
+
* 本地状态与服务端赛跑是正常的,客户端得容忍。
|
|
10
|
+
*/
|
|
11
|
+
export declare function reduceRecv(ctx: CallContext, type: string, data: Readonly<Record<string, unknown>>): MachineOutput<CallContext>;
|
|
12
|
+
//# sourceMappingURL=callRecv.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"callRecv.d.ts","sourceRoot":"","sources":["../../src/state/callRecv.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD,OAAO,KAAK,EAAgB,aAAa,EAAE,MAAM,YAAY,CAAC;AAa9D;;;;;;;GAOG;AACH,wBAAgB,UAAU,CACxB,GAAG,EAAE,WAAW,EAChB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACtC,aAAa,CAAC,WAAW,CAAC,CA2C5B"}
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import { normalizeReason } from '../reasons.js';
|
|
2
|
+
import { FrameType } from '../signaling/registry.js';
|
|
3
|
+
import { initialCallContext, out } from './callMachine.js';
|
|
4
|
+
import { bool, num, str, strArray } from './types.js';
|
|
5
|
+
/**
|
|
6
|
+
* 通话状态机的**下行帧**分支(RTC_PROTOCOL.md §5.1 的转移表右半边)。
|
|
7
|
+
*
|
|
8
|
+
* 与 callMachine.ts 拆开是因为体量红线(CONVENTIONS §2,400 行)——
|
|
9
|
+
* 「上行动作」与「下行帧」本来也是两组独立的关注点。
|
|
10
|
+
*/
|
|
11
|
+
/** CALL_INVITE_OK 是 call.invite 的应答类型。 */
|
|
12
|
+
const CALL_INVITE_OK = `${FrameType.callInvite}.ok`;
|
|
13
|
+
/**
|
|
14
|
+
* reduceRecv 处理一条下行帧。
|
|
15
|
+
*
|
|
16
|
+
* 两条优先级规则写在最前面,别挪:
|
|
17
|
+
* 1. **终态帧优先**——任何非 idle 状态收到 call.ended 都直达 idle(§5.1)。
|
|
18
|
+
* 2. **idle 下的迟到帧一律静默丢弃**:不抛回调、不发帧、不报错。
|
|
19
|
+
* 本地状态与服务端赛跑是正常的,客户端得容忍。
|
|
20
|
+
*/
|
|
21
|
+
export function reduceRecv(ctx, type, data) {
|
|
22
|
+
// **别的一通电话的帧一律不许碰当前这一通**(见 handleForeignCall)。
|
|
23
|
+
if (isForAnotherCall(ctx, data))
|
|
24
|
+
return handleForeignCall(ctx, type, data);
|
|
25
|
+
// 终态帧优先:**任何非 idle 状态收到 call.ended 都直达 idle**(§5.1)。
|
|
26
|
+
if (type === FrameType.callEnded)
|
|
27
|
+
return handleEnded(ctx, data);
|
|
28
|
+
// idle 下的迟到帧一律静默丢弃:不抛回调、不报错。只有两条例外要补发结束帧,见 handleLateFrame。
|
|
29
|
+
if (ctx.state === 'idle' && type !== FrameType.callIncoming)
|
|
30
|
+
return handleLateFrame(ctx, type, data);
|
|
31
|
+
switch (type) {
|
|
32
|
+
case FrameType.callIncoming:
|
|
33
|
+
return handleIncoming(ctx, data);
|
|
34
|
+
case CALL_INVITE_OK:
|
|
35
|
+
return handleInviteOk(ctx, data);
|
|
36
|
+
case FrameType.callConnected:
|
|
37
|
+
return handleConnected(ctx, data);
|
|
38
|
+
case FrameType.callAccepted:
|
|
39
|
+
return out(ctx, [], [{ cb: 'onUserAccept', args: { uid: str(data, 'uid') } }]);
|
|
40
|
+
case FrameType.callRejected:
|
|
41
|
+
return handleOutcome(ctx, data, 'onUserReject', 'onCallRejected');
|
|
42
|
+
case FrameType.callNoAnswer:
|
|
43
|
+
return handleOutcome(ctx, data, 'onUserNoResponse', 'onCallNoAnswer');
|
|
44
|
+
case FrameType.callBusy:
|
|
45
|
+
// 忙线没有对应的 onUser* —— 被叫压根没振铃(§4.3)。
|
|
46
|
+
return ctx.isGroup
|
|
47
|
+
? out(ctx)
|
|
48
|
+
: out(ctx, [], [{ cb: 'onCallBusy', args: { uid: str(data, 'uid') } }]);
|
|
49
|
+
case FrameType.callCancelled:
|
|
50
|
+
// 内部回调参数按一致性向量钉的线路字段名 by(四端共用,见 call_fsm.json);
|
|
51
|
+
// 公开事件字段改叫 uid 是 engineBus.ts 的 emitMachine 在进公开事件表那一步做的翻译。
|
|
52
|
+
return out(ctx, [], [{ cb: 'onCallCancelled', args: { by: str(data, 'by') } }]);
|
|
53
|
+
case FrameType.callHandledElsewhere:
|
|
54
|
+
return out(ctx, [], [
|
|
55
|
+
{
|
|
56
|
+
cb: 'onHandledOnOtherDevice',
|
|
57
|
+
args: { call_id: str(data, 'call_id'), action: str(data, 'action') },
|
|
58
|
+
},
|
|
59
|
+
]);
|
|
60
|
+
default:
|
|
61
|
+
// 其余(call.ringing、各种 .ok)不改状态也不抛回调。
|
|
62
|
+
return out(ctx);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* 这一帧说的是不是**别的一通电话**。
|
|
67
|
+
*
|
|
68
|
+
* 通话中被第三个人呼叫时,服务端判他忙线并给我们发一条 `call.ended{busy}`——
|
|
69
|
+
* 那条帧的 `call_id` 是**新来那通**的。原先这里不看 call_id,于是它被当成
|
|
70
|
+
* 「当前通话结束了」:媒体面直接关掉、通话页收起,而对面还好好地显示着通话中
|
|
71
|
+
* (真机日志 08:30:39,iOS 侧一串 `PC 状态 closed` 紧跟一条别的 call_id 的 callEnd)。
|
|
72
|
+
*/
|
|
73
|
+
function isForAnotherCall(ctx, data) {
|
|
74
|
+
const frameCallId = str(data, 'call_id');
|
|
75
|
+
return ctx.callId !== '' && frameCallId !== '' && frameCallId !== ctx.callId;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* 别的一通电话的帧:**一律不碰当前状态**。
|
|
79
|
+
*
|
|
80
|
+
* 只有终态帧要露个头——那说明「有人打进来,已经被自动回了忙线」,
|
|
81
|
+
* 界面据此提示一句谁来过电话(交互规则见 UX_FLOWS §06)。
|
|
82
|
+
*/
|
|
83
|
+
function handleForeignCall(ctx, type, data) {
|
|
84
|
+
if (type !== FrameType.callEnded)
|
|
85
|
+
return out(ctx);
|
|
86
|
+
return out(ctx, [], [
|
|
87
|
+
{
|
|
88
|
+
cb: 'onCallMissed',
|
|
89
|
+
// 状态机的 args 一律 snake_case(与向量、与另外三端同名);
|
|
90
|
+
// 出到公开事件时由 engineBus 的 camelizeArgs 统一转。
|
|
91
|
+
args: {
|
|
92
|
+
call_id: str(data, 'call_id'),
|
|
93
|
+
caller: str(data, 'caller'),
|
|
94
|
+
reason: str(data, 'reason'),
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
]);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* handleLateFrame:idle 下迟到的帧**照旧丢弃**(优先级规则 2),只有两条例外——
|
|
101
|
+
* 它们说明服务端那边**还有一通挂着本端的电话**,而本地早就收场了
|
|
102
|
+
* (红键强制收场时请求还在路上,或请求超时回滚之后应答才到):
|
|
103
|
+
*
|
|
104
|
+
* - `call.invite.ok`:邀请在服务端落地了,被叫正在响铃。补发 `call.cancel`,
|
|
105
|
+
* 否则被叫一直响到超时,而主叫这边一个界面都没有。
|
|
106
|
+
* - `call.connected`:有人已经接起来了(cancel 来不及,或本端是被叫、accept 已落地)。
|
|
107
|
+
* 补发 `call.hangup`,否则服务端一直把本端当成在通话里。
|
|
108
|
+
*
|
|
109
|
+
* 本地状态不动、不抛回调。补发的帧被拒(比如通话已经结束)只换回一条 error 事件,无害。
|
|
110
|
+
* 与 iOS `IMCallMachine.handleLateFrame` 同形。
|
|
111
|
+
*/
|
|
112
|
+
function handleLateFrame(ctx, type, data) {
|
|
113
|
+
const callId = str(data, 'call_id');
|
|
114
|
+
if (callId === '')
|
|
115
|
+
return out(ctx);
|
|
116
|
+
if (type === CALL_INVITE_OK) {
|
|
117
|
+
return out(ctx, [{ type: FrameType.callCancel, data: { call_id: callId } }]);
|
|
118
|
+
}
|
|
119
|
+
if (type === FrameType.callConnected) {
|
|
120
|
+
return out(ctx, [{ type: FrameType.callHangup, data: { call_id: callId } }]);
|
|
121
|
+
}
|
|
122
|
+
return out(ctx);
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* handleInviteOk:记下 call_id / room_id。
|
|
126
|
+
*
|
|
127
|
+
* **invite.ok 回来之前按过取消**(callMachine 的 `cancel`,那时没有 call_id 可发):
|
|
128
|
+
* 现在有了,立刻补发 `call.cancel`——不必等 uikit 的看门狗。与 iOS `IMCallMachine.reduceRecv` 同形。
|
|
129
|
+
*/
|
|
130
|
+
function handleInviteOk(ctx, data) {
|
|
131
|
+
const next = { ...ctx, callId: str(data, 'call_id'), roomId: str(data, 'room_id') };
|
|
132
|
+
if (!ctx.cancelPending || next.callId === '')
|
|
133
|
+
return out(next);
|
|
134
|
+
return out({ ...next, cancelPending: false }, [
|
|
135
|
+
{ type: FrameType.callCancel, data: { call_id: next.callId } },
|
|
136
|
+
]);
|
|
137
|
+
}
|
|
138
|
+
function handleIncoming(ctx, data) {
|
|
139
|
+
if (ctx.state !== 'idle')
|
|
140
|
+
return out(ctx);
|
|
141
|
+
const mediaType = str(data, 'media_type') === 'video' ? 'video' : 'audio';
|
|
142
|
+
const caller = str(data, 'caller');
|
|
143
|
+
// inviter 是「谁把你拉进来的」(invite_more 时不是发起人);旧服务端不带它,回落 caller。
|
|
144
|
+
const inviter = str(data, 'inviter') || caller;
|
|
145
|
+
const next = {
|
|
146
|
+
...ctx,
|
|
147
|
+
state: 'ringing',
|
|
148
|
+
role: 'callee',
|
|
149
|
+
callId: str(data, 'call_id'),
|
|
150
|
+
roomId: str(data, 'room_id'),
|
|
151
|
+
mediaType,
|
|
152
|
+
isGroup: bool(data, 'is_group'),
|
|
153
|
+
// 记下来给 onCallBegin 兜底用(HOST_INTEGRATION_DESIGN §3.3):接通时优先用
|
|
154
|
+
// call.connected 自己带的值,这里存的是万一它为空时的回落。
|
|
155
|
+
chatGroupId: str(data, 'chat_group_id'),
|
|
156
|
+
userData: str(data, 'user_data'),
|
|
157
|
+
};
|
|
158
|
+
return out(next, [], [
|
|
159
|
+
{
|
|
160
|
+
cb: 'onCallReceived',
|
|
161
|
+
args: {
|
|
162
|
+
call_id: next.callId,
|
|
163
|
+
caller,
|
|
164
|
+
inviter,
|
|
165
|
+
// **原样带上**:群通话里被叫要靠它摆占位格(见 events.ts 的字段注释)。
|
|
166
|
+
callee_ids: strArray(data, 'callee_ids'),
|
|
167
|
+
media_type: mediaType,
|
|
168
|
+
is_group: next.isGroup,
|
|
169
|
+
chat_group_id: next.chatGroupId,
|
|
170
|
+
user_data: next.userData,
|
|
171
|
+
},
|
|
172
|
+
},
|
|
173
|
+
]);
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* handleConnected:拿到 room_token,抛 onCallBegin,并**立刻发 room.join**。
|
|
177
|
+
*
|
|
178
|
+
* onCallBegin 抛在进入 connecting 时(不是 connected)——草图 §09 的时序就是这样:
|
|
179
|
+
* 双方在 room_ready(现名 call.connected)那一刻同时开始计时。
|
|
180
|
+
*/
|
|
181
|
+
function handleConnected(ctx, data) {
|
|
182
|
+
if (ctx.state !== 'inviting' && ctx.state !== 'ringing' && ctx.state !== 'accepting') {
|
|
183
|
+
return out(ctx);
|
|
184
|
+
}
|
|
185
|
+
const roomId = str(data, 'room_id');
|
|
186
|
+
const roomToken = str(data, 'room_token');
|
|
187
|
+
const mediaType = str(data, 'media_type') === 'video' ? 'video' : ctx.mediaType;
|
|
188
|
+
// 群号 / user_data:优先取 call.connected 自己带的值,为空才回落到本通 call.incoming /
|
|
189
|
+
// call() 选项里记下的那份(兼容还没升级的旧服务端,HOST_INTEGRATION_DESIGN §3.3)。
|
|
190
|
+
const chatGroupId = str(data, 'chat_group_id') || ctx.chatGroupId;
|
|
191
|
+
const userData = str(data, 'user_data') || ctx.userData;
|
|
192
|
+
const next = {
|
|
193
|
+
...ctx,
|
|
194
|
+
state: 'connecting',
|
|
195
|
+
callId: str(data, 'call_id') || ctx.callId,
|
|
196
|
+
roomId,
|
|
197
|
+
roomToken,
|
|
198
|
+
mediaType,
|
|
199
|
+
isGroup: bool(data, 'is_group') || ctx.isGroup,
|
|
200
|
+
connectedAtMs: num(data, 'connected_at_ms'),
|
|
201
|
+
chatGroupId,
|
|
202
|
+
userData,
|
|
203
|
+
};
|
|
204
|
+
return out(next, [{ type: FrameType.roomJoin, data: { room_id: roomId, room_token: roomToken } }], [
|
|
205
|
+
{
|
|
206
|
+
cb: 'onCallBegin',
|
|
207
|
+
args: {
|
|
208
|
+
call_id: next.callId,
|
|
209
|
+
room_id: roomId,
|
|
210
|
+
media_type: mediaType,
|
|
211
|
+
is_group: next.isGroup,
|
|
212
|
+
role: next.role,
|
|
213
|
+
// call.join 进来的人没收过 call.incoming,caller 只能从这里知道是谁打的(协议 §4.2)。
|
|
214
|
+
caller: str(data, 'caller'),
|
|
215
|
+
chat_group_id: chatGroupId,
|
|
216
|
+
user_data: userData,
|
|
217
|
+
},
|
|
218
|
+
},
|
|
219
|
+
]);
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* handleOutcome 处理某成员的裁决。
|
|
223
|
+
*
|
|
224
|
+
* **便利事件只在 1v1 抛**(不变量 I7):群里一个人拒接,通话还在继续,
|
|
225
|
+
* 后面并不会紧跟 onCallEnd,抛便利事件就自相矛盾了。
|
|
226
|
+
*/
|
|
227
|
+
function handleOutcome(ctx, data, userCb, convenienceCb) {
|
|
228
|
+
const uid = str(data, 'uid');
|
|
229
|
+
const emit = [{ cb: userCb, args: { uid } }];
|
|
230
|
+
if (!ctx.isGroup)
|
|
231
|
+
emit.push({ cb: convenienceCb, args: { uid } });
|
|
232
|
+
return out(ctx, [], emit);
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* handleEnded:唯一的终态处理。
|
|
236
|
+
*
|
|
237
|
+
* **收到 call.ended 后禁止再发 room.leave**(不变量 I6)——服务端在结束通话时
|
|
238
|
+
* 已经清掉了房间成员,再发只会换回 1201/1203。
|
|
239
|
+
*/
|
|
240
|
+
function handleEnded(ctx, data) {
|
|
241
|
+
if (ctx.state === 'idle')
|
|
242
|
+
return out(ctx);
|
|
243
|
+
return out({ ...initialCallContext }, [], [
|
|
244
|
+
{
|
|
245
|
+
cb: 'onCallEnd',
|
|
246
|
+
args: {
|
|
247
|
+
call_id: str(data, 'call_id'),
|
|
248
|
+
reason: normalizeReason(data['reason']),
|
|
249
|
+
duration_sec: num(data, 'duration_sec'),
|
|
250
|
+
ended_by: str(data, 'ended_by'),
|
|
251
|
+
},
|
|
252
|
+
},
|
|
253
|
+
]);
|
|
254
|
+
}
|
|
255
|
+
//# sourceMappingURL=callRecv.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"callRecv.js","sourceRoot":"","sources":["../../src/state/callRecv.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { CallContext } from './callMachine.js';
|
|
2
|
+
import type { RoomContext } from './roomMachine.js';
|
|
3
|
+
import type { MachineInput, MachineOutput } from './types.js';
|
|
4
|
+
/**
|
|
5
|
+
* engine 的总状态:把通话机与房间机合起来,并处理只有「合起来」才说得清的事。
|
|
6
|
+
*
|
|
7
|
+
* 四件只有这一层能做的事:
|
|
8
|
+
* 1. **连接级事件**(onConnected / onDisconnected / onKickedOut)由这里抛——
|
|
9
|
+
* 它们既不属于某次通话,也不属于某个房间。(`onDisconnected` 只用来驱动状态迁移,
|
|
10
|
+
* 真正发给宿主的那条由连接层发,因为关闭码只有它知道——见 engine.ts 的 dispatch。)
|
|
11
|
+
* 2. **重连恢复失败**时,房间回 idle **且**通话要本地合成 `onCallEnd(network)`
|
|
12
|
+
* (协议不变量 I8)——服务端那条 ended 帧送不到我们手里了。
|
|
13
|
+
* 3. **通话机产出的 room.join** 要转成房间机的 join 动作,否则房间状态机不知道
|
|
14
|
+
* 自己正在进房,之后的 join.ok 就没人接。
|
|
15
|
+
* 4. **通话结束时房间要回 idle**。这条是 3 的反向,漏了它的后果比漏 3 还隐蔽:
|
|
16
|
+
* `call.ended` 之后服务端就把房间销毁了,而房间机还停在 joined,
|
|
17
|
+
* 于是**之后每一帧都发向一个已经不存在的房间**(服务端回 1201 room_not_found),
|
|
18
|
+
* 下一次 joinRoom 还会因为「不在 idle」被本地拒掉——界面永远停在「接通中」。
|
|
19
|
+
*/
|
|
20
|
+
/** EngineContext 是 engine 的完整状态。 */
|
|
21
|
+
export interface EngineContext {
|
|
22
|
+
readonly room: RoomContext;
|
|
23
|
+
readonly call: CallContext;
|
|
24
|
+
/**
|
|
25
|
+
* **本端**这一场从哪一刻算起(本机时钟,毫秒):抛 `onCallBegin` 时记下,通话回 idle 清零。
|
|
26
|
+
*
|
|
27
|
+
* 强制收场本地算时长要用它(`state/forceEnd.ts`)。整通电话的 `connected_at_ms` 是第一个人
|
|
28
|
+
* 接起来的时刻,中途被拉进来的人拿它算会偏大(2026-09-15 10:05 iOS frank 待了约 6 秒,
|
|
29
|
+
* 本地写成 124 秒)。不进一致性向量:向量只断言通话 / 房间那几个键。与 iOS `callStartedAtMS` 同形。
|
|
30
|
+
*/
|
|
31
|
+
readonly callStartedAtMs: number;
|
|
32
|
+
}
|
|
33
|
+
/** initialEngineContext 是全空态。 */
|
|
34
|
+
export declare const initialEngineContext: EngineContext;
|
|
35
|
+
/**
|
|
36
|
+
* reduceEngine 是 engine 状态的唯一入口。
|
|
37
|
+
*
|
|
38
|
+
* `nowMs` 只用来给 `callStartedAtMs` 打点,状态转移本身不看它(I4:禁止由定时器改状态)。
|
|
39
|
+
*/
|
|
40
|
+
export declare function reduceEngine(ctx: EngineContext, input: MachineInput, nowMs?: number): MachineOutput<EngineContext>;
|
|
41
|
+
//# sourceMappingURL=engineMachine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engineMachine.d.ts","sourceRoot":"","sources":["../../src/state/engineMachine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD,OAAO,KAAK,EAAgB,YAAY,EAAE,aAAa,EAAiB,MAAM,YAAY,CAAC;AAG3F;;;;;;;;;;;;;;;GAeG;AAEH,oCAAoC;AACpC,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B;;;;;;OAMG;IACH,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;CAClC;AAED,iCAAiC;AACjC,eAAO,MAAM,oBAAoB,EAAE,aAIlC,CAAC;AAiBF;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,GAAG,EAAE,aAAa,EAClB,KAAK,EAAE,YAAY,EACnB,KAAK,GAAE,MAAmB,GACzB,aAAa,CAAC,aAAa,CAAC,CAE9B"}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import { initialCallContext, reduceCall, synthesizeNetworkEnd } from './callMachine.js';
|
|
2
|
+
import { clearedRoom, initialRoomContext, reduceRoom, resumeRoom } from './roomMachine.js';
|
|
3
|
+
import { bool, str } from './types.js';
|
|
4
|
+
/** initialEngineContext 是全空态。 */
|
|
5
|
+
export const initialEngineContext = {
|
|
6
|
+
room: initialRoomContext,
|
|
7
|
+
call: initialCallContext,
|
|
8
|
+
callStartedAtMs: 0,
|
|
9
|
+
};
|
|
10
|
+
const CALL_ACTS = new Set(['call', 'accept', 'reject', 'cancel', 'hangup', 'invite_more', 'join_call']);
|
|
11
|
+
const ROOM_ACTS = new Set([
|
|
12
|
+
'join',
|
|
13
|
+
'leave',
|
|
14
|
+
'publish',
|
|
15
|
+
'unpublish',
|
|
16
|
+
'mute',
|
|
17
|
+
'subscribe',
|
|
18
|
+
'unsubscribe',
|
|
19
|
+
'update_layer',
|
|
20
|
+
'restart_pub_ice',
|
|
21
|
+
]);
|
|
22
|
+
/** ROOM_FAILURES 是帧循环把「房间帧没送到」翻译成的内部事件,全归房间机。 */
|
|
23
|
+
const ROOM_FAILURES = new Set(['join_failed', 'leave_failed', 'publish_failed', 'subscribe_failed']);
|
|
24
|
+
/**
|
|
25
|
+
* reduceEngine 是 engine 状态的唯一入口。
|
|
26
|
+
*
|
|
27
|
+
* `nowMs` 只用来给 `callStartedAtMs` 打点,状态转移本身不看它(I4:禁止由定时器改状态)。
|
|
28
|
+
*/
|
|
29
|
+
export function reduceEngine(ctx, input, nowMs = Date.now()) {
|
|
30
|
+
return stampCallStart(ctx, reduceInput(ctx, input), nowMs);
|
|
31
|
+
}
|
|
32
|
+
function reduceInput(ctx, input) {
|
|
33
|
+
if (input.kind === 'recv' && input.type === 'sys.hello.ok') {
|
|
34
|
+
return handleHelloOk(ctx, input.data);
|
|
35
|
+
}
|
|
36
|
+
if (input.kind === 'internal')
|
|
37
|
+
return handleInternal(ctx, input);
|
|
38
|
+
if (input.kind === 'recv')
|
|
39
|
+
return routeFrame(ctx, input);
|
|
40
|
+
return routeAct(ctx, input);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* stampCallStart:这一步抛了 `onCallBegin` 就记下此刻;通话回到 idle 就清零;其余沿用。
|
|
44
|
+
*
|
|
45
|
+
* **统一放在入口**:各分支有的沿用 ctx、有的重建 ctx,挨个分支去记迟早漏一条。
|
|
46
|
+
*/
|
|
47
|
+
function stampCallStart(before, result, nowMs) {
|
|
48
|
+
let callStartedAtMs = before.callStartedAtMs;
|
|
49
|
+
if (result.emit.some((event) => event.cb === 'onCallBegin')) {
|
|
50
|
+
callStartedAtMs = nowMs;
|
|
51
|
+
}
|
|
52
|
+
else if (result.state.call.state === 'idle') {
|
|
53
|
+
callStartedAtMs = 0;
|
|
54
|
+
}
|
|
55
|
+
if (result.state.callStartedAtMs === callStartedAtMs)
|
|
56
|
+
return result;
|
|
57
|
+
return { ...result, state: { ...result.state, callStartedAtMs } };
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* handleHelloOk:握手成功。`resumed=false` 时**房间与通话都要归零**——
|
|
61
|
+
* 服务端那边的会话已经过期,装作还在只会让 UI 撒谎。
|
|
62
|
+
*/
|
|
63
|
+
function handleHelloOk(ctx, data) {
|
|
64
|
+
const resumed = bool(data, 'resumed');
|
|
65
|
+
const emit = [
|
|
66
|
+
{ cb: 'onConnected', args: { session_id: str(data, 'session_id'), resumed } },
|
|
67
|
+
];
|
|
68
|
+
if (!resumed) {
|
|
69
|
+
const dropped = dropLostSession(ctx);
|
|
70
|
+
return { state: dropped.state, send: dropped.send, emit: [...emit, ...dropped.emit] };
|
|
71
|
+
}
|
|
72
|
+
const room = resumeRoom(ctx.room, true);
|
|
73
|
+
emit.push(...room.emit);
|
|
74
|
+
return { state: { ...ctx, room: room.state }, send: [...room.send], emit };
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* dropLostSession 收拾「服务端那侧的会话已经没了」这一件事:房间与通话都要收场。
|
|
78
|
+
*
|
|
79
|
+
* 「重连上了但 `resumed=false`」与「断得太久 `session_unrecoverable`」是同一件事的两个
|
|
80
|
+
* 到达时机,所以共用这一段。
|
|
81
|
+
*
|
|
82
|
+
* # 必须给宿主一个收场信号
|
|
83
|
+
*
|
|
84
|
+
* `resumeRoom(ctx, false)` 只是把房间清成 idle,**一个事件都不抛**。有 call 的场合
|
|
85
|
+
* 还有 `onCallEnd(network)` 兜着,可**会议是直接 joinRoom 的、压根没有 call**——
|
|
86
|
+
* 于是房间机悄悄回了 idle,而界面还显示着「会议中」、计时器还在走,用户完全不知道
|
|
87
|
+
* 自己已经掉出去了;更糟的是 `onCallEnd/onRoomLeft` 都没抛,engine 那边的
|
|
88
|
+
* `LEAVE_CALLBACKS` 不命中、`bridge.reset()` 不跑,**上一轮的 PeerConnection 会被
|
|
89
|
+
* 带进下一次进房**(正是 mediaBridge 注释里点名的黑屏成因)。
|
|
90
|
+
*
|
|
91
|
+
* 所以:有通话就抛 `onCallEnd`(唯一出口,不再补 `onRoomLeft`,否则宿主记两遍账),
|
|
92
|
+
* 没通话但在房里就补一条 `onRoomLeft`——房间的收场信号就是它。
|
|
93
|
+
* **iOS 的 `IMRoomMachine.resume` 与 Android 的 `IMRoomMachine.resume` 是同一处漏洞,
|
|
94
|
+
* 补这条要三端一起补。**
|
|
95
|
+
*/
|
|
96
|
+
function dropLostSession(ctx) {
|
|
97
|
+
const room = resumeRoom(ctx.room, false);
|
|
98
|
+
const emit = [...room.emit];
|
|
99
|
+
let call = ctx.call;
|
|
100
|
+
if (ctx.call.state !== 'idle') {
|
|
101
|
+
// 不变量 I8 的那个唯一例外:服务端的 call.ended 送不到,本地合成一条。
|
|
102
|
+
const synthesized = synthesizeNetworkEnd(ctx.call, Date.now());
|
|
103
|
+
call = synthesized.state;
|
|
104
|
+
emit.push(...synthesized.emit);
|
|
105
|
+
}
|
|
106
|
+
else if (ctx.room.state !== 'idle') {
|
|
107
|
+
emit.push({ cb: 'onRoomLeft', args: { room_id: ctx.room.roomId } });
|
|
108
|
+
}
|
|
109
|
+
return { state: { ...ctx, room: room.state, call }, send: [...room.send], emit };
|
|
110
|
+
}
|
|
111
|
+
function handleInternal(ctx, input) {
|
|
112
|
+
const { name } = input;
|
|
113
|
+
/*
|
|
114
|
+
**服务端那一侧已经不可能再恢复这条会话了**(§1.4 的恢复窗口过了)。
|
|
115
|
+
|
|
116
|
+
语义与「重连上了但 resumed=false」完全一样,所以走同一段代码:房间归零、
|
|
117
|
+
通话本地合成一条 ended{network}。差别只在**不必等重连成功**——
|
|
118
|
+
网络一直不回来的话那一刻永远不会到,界面就永远停在「正在重连」、
|
|
119
|
+
连挂断都点不动(真机 2026-09-08 的 iOS 端)。
|
|
120
|
+
|
|
121
|
+
「什么时候算过了窗口」由连接层算(只有它知道心跳周期),见 ResumeDeadline。
|
|
122
|
+
*/
|
|
123
|
+
if (name === 'session_unrecoverable')
|
|
124
|
+
return dropLostSession(ctx);
|
|
125
|
+
if (name === 'ws_closed_4403') {
|
|
126
|
+
// 被踢:什么都不留。重连没有意义——那等于跟另一台设备打架。
|
|
127
|
+
return {
|
|
128
|
+
state: { ...ctx, room: clearedRoom('idle'), call: initialCallContext },
|
|
129
|
+
send: [],
|
|
130
|
+
// 不带关闭码:这个内部事件也被「鉴权连续失败」复用,那时真实关闭码是 4401。
|
|
131
|
+
// 关闭码由连接层原样上报(见 engine.ts 里为什么状态机这条不外发)。
|
|
132
|
+
emit: [{ cb: 'onKickedOut', args: {} }, { cb: 'onDisconnected', args: {} }],
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
if (name === 'disconnected') {
|
|
136
|
+
const room = reduceRoom(ctx.room, { kind: 'internal', name });
|
|
137
|
+
return {
|
|
138
|
+
state: { ...ctx, room: room.state },
|
|
139
|
+
send: [],
|
|
140
|
+
emit: [{ cb: 'onDisconnected', args: {} }, ...room.emit],
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
if (name === 'call_failed') {
|
|
144
|
+
// 交给通话机回 idle;它抛的 onCallEnd 会顺带把房间也清掉(见 liftCall)。
|
|
145
|
+
return liftCall(ctx, reduceCall(ctx.call, { kind: 'internal', name }));
|
|
146
|
+
}
|
|
147
|
+
// 房间那几条失败回滚都归房间机;不显式路由的话它们会落到通话机去,被静默丢掉。
|
|
148
|
+
if (ROOM_FAILURES.has(name)) {
|
|
149
|
+
const room = reduceRoom(ctx.room, input);
|
|
150
|
+
return { state: { ...ctx, room: room.state }, send: [...room.send], emit: [...room.emit] };
|
|
151
|
+
}
|
|
152
|
+
// 其余内部事件(media_ready)交给通话机。
|
|
153
|
+
const call = reduceCall(ctx.call, { kind: 'internal', name });
|
|
154
|
+
return { state: { ...ctx, call: call.state }, send: [...call.send], emit: [...call.emit] };
|
|
155
|
+
}
|
|
156
|
+
function routeFrame(ctx, input) {
|
|
157
|
+
if (input.type.startsWith('call.'))
|
|
158
|
+
return liftCall(ctx, reduceCall(ctx.call, input));
|
|
159
|
+
if (input.type.startsWith('room.')) {
|
|
160
|
+
const room = reduceRoom(ctx.room, input);
|
|
161
|
+
return { state: { ...ctx, room: room.state }, send: [...room.send], emit: [...room.emit] };
|
|
162
|
+
}
|
|
163
|
+
return { state: ctx, send: [], emit: [] };
|
|
164
|
+
}
|
|
165
|
+
function routeAct(ctx, input) {
|
|
166
|
+
if (CALL_ACTS.has(input.op))
|
|
167
|
+
return liftCall(ctx, reduceCall(ctx.call, input));
|
|
168
|
+
if (ROOM_ACTS.has(input.op)) {
|
|
169
|
+
const room = reduceRoom(ctx.room, input);
|
|
170
|
+
return { state: { ...ctx, room: room.state }, send: [...room.send], emit: [...room.emit] };
|
|
171
|
+
}
|
|
172
|
+
return { state: ctx, send: [], emit: [] };
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* liftCall 把通话机的输出抬到 engine 层,并**把 room.join 转交给房间机**。
|
|
176
|
+
*
|
|
177
|
+
* 不做这一步的话,房间机不知道自己正在进房,随后的 `room.join.ok` 就没人接,
|
|
178
|
+
* UI 会停在「接通中」不动。
|
|
179
|
+
*/
|
|
180
|
+
function liftCall(ctx, result) {
|
|
181
|
+
const send = [];
|
|
182
|
+
let room = ctx.room;
|
|
183
|
+
const emit = [...result.emit];
|
|
184
|
+
for (const frame of result.send) {
|
|
185
|
+
if (frame.type !== 'room.join') {
|
|
186
|
+
send.push(frame);
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
const joined = reduceRoom(room, {
|
|
190
|
+
kind: 'act',
|
|
191
|
+
op: 'join',
|
|
192
|
+
args: { room_id: frame.data['room_id'], room_token: frame.data['room_token'] },
|
|
193
|
+
});
|
|
194
|
+
room = joined.state;
|
|
195
|
+
send.push(...joined.send);
|
|
196
|
+
emit.push(...joined.emit);
|
|
197
|
+
}
|
|
198
|
+
/*
|
|
199
|
+
通话结束 = 房间没了。服务端在发出 `call.ended` 的同时就销毁了房间(协议 §4.4),
|
|
200
|
+
所以这里只是**本地归零**,不发 room.leave——那一帧只会换回一个 1201。
|
|
201
|
+
|
|
202
|
+
也不补抛 onRoomLeft:`onCallEnd` 是所有结束分支的唯一出口(设计 §7.5),
|
|
203
|
+
为同一件事抛两个回调会让宿主的记账重复。
|
|
204
|
+
*/
|
|
205
|
+
if (emit.some((event) => event.cb === 'onCallEnd')) {
|
|
206
|
+
room = clearedRoom('idle');
|
|
207
|
+
}
|
|
208
|
+
return { state: { ...ctx, room, call: result.state }, send, emit };
|
|
209
|
+
}
|
|
210
|
+
//# sourceMappingURL=engineMachine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engineMachine.js","sourceRoot":"","sources":["../../src/state/engineMachine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { CallEndReasonValue } from '../reasons.js';
|
|
2
|
+
import type { CallContext } from './callMachine.js';
|
|
3
|
+
import type { EngineContext } from './engineMachine.js';
|
|
4
|
+
import type { MachineOutput, OutgoingFrame } from './types.js';
|
|
5
|
+
/**
|
|
6
|
+
* 强制收场:红键按下去**等不到结束事件**时的出口(门面见 `CallEngine.forceEnd`)。
|
|
7
|
+
*
|
|
8
|
+
* # 为什么 hangup 不够
|
|
9
|
+
*
|
|
10
|
+
* hangup 只发帧,状态由随后的 `call.ended` 推进——服务端才是裁决方(§5.1)。帧要是根本没发出去,
|
|
11
|
+
* 这一场就永远收不掉:2026-09-13 14:54 iOS frank 按了挂断,`call.hangup` 一帧没到服务端,
|
|
12
|
+
* Kit 的看门狗把界面收了,Engine 却还留在通话与房间里,别人一直看得见他,直到 14:58 整通结束。
|
|
13
|
+
*
|
|
14
|
+
* # 这里只算「该发什么、收成什么样」
|
|
15
|
+
*
|
|
16
|
+
* 纯函数,与 `dropLostSession` 同一个形状:通话机、房间机一起归零,抛唯一的结束出口。
|
|
17
|
+
* **发帧由帧循环直接交给信令连接**(不排在在途请求后面),关媒体走既有的 `LEAVE_CALLBACKS`。
|
|
18
|
+
* 五端同形:iOS `IMEngineMachine.forceEnd`、Android 同名。
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* forceEnd 算出强制收场的结果。没有进行中的通话也不在房里时原样返回(`emit` 为空)。
|
|
22
|
+
*
|
|
23
|
+
* 时长与恢复失败时 I8 的那条例外同一个算法:本地已经收场,服务端那条带真值的 `call.ended`
|
|
24
|
+
* 随后会因为 idle 被丢掉,没有更准的值可用。起点优先用**本端**进来那一刻(`callStartedAtMs`),
|
|
25
|
+
* 没记到才退回整通电话的 `connected_at_ms`——中途被拉进来的人用后者会偏大
|
|
26
|
+
* (2026-09-15 10:05 iOS frank 待了约 6 秒,本地写成 124 秒)。
|
|
27
|
+
*
|
|
28
|
+
* `reason` 不给就按此刻状态挑(红键);给了就用它——`room.publish` 被拒时帧循环传 `error`,
|
|
29
|
+
* 那不是用户挂的,写成 hangup 是撒谎。
|
|
30
|
+
*/
|
|
31
|
+
export declare function forceEnd(ctx: EngineContext, nowMs: number, reasonOverride?: CallEndReasonValue): MachineOutput<EngineContext>;
|
|
32
|
+
/**
|
|
33
|
+
* endFrames 按通话此刻的状态挑结束帧,以及本地收场写哪个结束原因。
|
|
34
|
+
*
|
|
35
|
+
* - `accepting` 发 **reject + hangup 两帧**:accept 有没有在服务端落地,本端不知道。
|
|
36
|
+
* 还在响铃就是 reject 生效(随后那条 hangup 被拒,无害);已经接起来就是 hangup 生效。
|
|
37
|
+
* - `inviting` 还没拿到 call_id(`call.invite.ok` 没回来)时**此刻发不了 cancel**,
|
|
38
|
+
* 由那条 invite.ok 迟到时补发(`callRecv.ts` 的 `handleLateFrame`)。
|
|
39
|
+
*/
|
|
40
|
+
export declare function endFrames(call: CallContext): {
|
|
41
|
+
readonly frames: OutgoingFrame[];
|
|
42
|
+
readonly reason: CallEndReasonValue;
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=forceEnd.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"forceEnd.d.ts","sourceRoot":"","sources":["../../src/state/forceEnd.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAExD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE/D;;;;;;;;;;;;;;GAcG;AAEH;;;;;;;;;;GAUG;AACH,wBAAgB,QAAQ,CACtB,GAAG,EAAE,aAAa,EAClB,KAAK,EAAE,MAAM,EACb,cAAc,CAAC,EAAE,kBAAkB,GAClC,aAAa,CAAC,aAAa,CAAC,CA+B9B;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,WAAW,GAAG;IAC5C,QAAQ,CAAC,MAAM,EAAE,aAAa,EAAE,CAAC;IACjC,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAC;CACrC,CAwBA"}
|