789 lines
26 KiB
TypeScript
789 lines
26 KiB
TypeScript
// Metro module 12865 (f12866).
|
|
import DeveloperOptionsStore from "../stores/DeveloperOptionsStore";
|
|
import { MediaTypes, MediaEngineContextTypes, SpeakingFlags } from "../_bundle/Module4250";
|
|
import Durations from "../utils/Durations";
|
|
import TypedEventEmitter from "../_bundle/TypedEventEmitter";
|
|
import Backoff from "../_bundle/Backoff";
|
|
import Logger from "../modules/debug/Logger";
|
|
import { now } from "../_bundle/sleep";
|
|
import { isPlatformEmbedded } from "../utils/PlatformUtils";
|
|
import Module38 from "../_bundle/Module38";
|
|
function $mk90528() {
|
|
return (a0) => ({
|
|
name: a0.name,
|
|
type: a0.type,
|
|
priority: 1000 * a0.priority,
|
|
payload_type: a0.payloadType,
|
|
rtx_payload_type: a0.rtxPayloadType,
|
|
encode: a0.encode,
|
|
decode: a0.decode
|
|
});
|
|
}
|
|
function $mk90529() {
|
|
return (a0) => ({
|
|
type: a0.type,
|
|
rid: a0.rid,
|
|
ssrc: a0.ssrc,
|
|
active: a0.active,
|
|
quality: a0.quality,
|
|
rtx_ssrc: a0.rtxSsrc,
|
|
max_bitrate: a0.maxBitrate,
|
|
max_framerate: a0.maxFrameRate,
|
|
max_resolution: a0.maxResolution != null ? {
|
|
type: a0.maxResolution.type,
|
|
width: a0.maxResolution.width,
|
|
height: a0.maxResolution.height
|
|
} : void 0
|
|
});
|
|
}
|
|
function $mk90530($env) {
|
|
return (a0) => {
|
|
const type = a0.type;
|
|
return {
|
|
type: type === "audio" ? MediaTypes.AUDIO : type === "test" ? MediaTypes.TEST : type === "screen" ? MediaTypes.SCREEN : MediaTypes.VIDEO,
|
|
rid: a0.rid,
|
|
ssrc: a0.ssrc,
|
|
rtxSsrc: a0.rtx_ssrc,
|
|
active: a0.active,
|
|
quality: a0.quality,
|
|
maxBitrate: a0.max_bitrate,
|
|
maxFrameRate: a0.max_framerate,
|
|
maxResolution: a0.max_resolution != null ? {
|
|
type: a0.max_resolution.type,
|
|
width: a0.max_resolution.width,
|
|
height: a0.max_resolution.height
|
|
} : void 0
|
|
};
|
|
};
|
|
}
|
|
let c8870_8, c8870_9, c8870_10, c8870_11, c8870_12, c8870_13, c8870_14, c8870_15;
|
|
let env8870 = {};
|
|
const noop = function noop() {};
|
|
c8870_8 = {
|
|
IDENTIFY: 0,
|
|
0: "IDENTIFY",
|
|
SELECT_PROTOCOL: 1,
|
|
1: "SELECT_PROTOCOL",
|
|
READY: 2,
|
|
2: "READY",
|
|
HEARTBEAT: 3,
|
|
3: "HEARTBEAT",
|
|
SELECT_PROTOCOL_ACK: 4,
|
|
4: "SELECT_PROTOCOL_ACK",
|
|
SPEAKING: 5,
|
|
5: "SPEAKING",
|
|
HEARTBEAT_ACK: 6,
|
|
6: "HEARTBEAT_ACK",
|
|
RESUME: 7,
|
|
7: "RESUME",
|
|
HELLO: 8,
|
|
8: "HELLO",
|
|
RESUMED: 9,
|
|
9: "RESUMED",
|
|
CLIENT_CONNECT: 11,
|
|
11: "CLIENT_CONNECT",
|
|
VIDEO: 12,
|
|
12: "VIDEO",
|
|
CLIENT_DISCONNECT: 13,
|
|
13: "CLIENT_DISCONNECT",
|
|
SESSION_UPDATE: 14,
|
|
14: "SESSION_UPDATE",
|
|
MEDIA_SINK_WANTS: 15,
|
|
15: "MEDIA_SINK_WANTS",
|
|
VOICE_BACKEND_VERSION: 16,
|
|
16: "VOICE_BACKEND_VERSION",
|
|
CHANNEL_OPTIONS_UPDATE: 17,
|
|
17: "CHANNEL_OPTIONS_UPDATE",
|
|
FLAGS: 18,
|
|
18: "FLAGS",
|
|
PLATFORM: 20,
|
|
20: "PLATFORM",
|
|
DAVE_PROTOCOL_PREPARE_TRANSITION: 21,
|
|
21: "DAVE_PROTOCOL_PREPARE_TRANSITION",
|
|
DAVE_PROTOCOL_EXECUTE_TRANSITION: 22,
|
|
22: "DAVE_PROTOCOL_EXECUTE_TRANSITION",
|
|
DAVE_PROTOCOL_READY_FOR_TRANSITION: 23,
|
|
23: "DAVE_PROTOCOL_READY_FOR_TRANSITION",
|
|
DAVE_PROTOCOL_PREPARE_EPOCH: 24,
|
|
24: "DAVE_PROTOCOL_PREPARE_EPOCH",
|
|
MLS_EXTERNAL_SENDER_PACKAGE: 25,
|
|
25: "MLS_EXTERNAL_SENDER_PACKAGE",
|
|
MLS_KEY_PACKAGE: 26,
|
|
26: "MLS_KEY_PACKAGE",
|
|
MLS_PROPOSALS: 27,
|
|
27: "MLS_PROPOSALS",
|
|
MLS_COMMIT_WELCOME: 28,
|
|
28: "MLS_COMMIT_WELCOME",
|
|
MLS_PREPARE_COMMIT_TRANSITION: 29,
|
|
29: "MLS_PREPARE_COMMIT_TRANSITION",
|
|
MLS_WELCOME: 30,
|
|
30: "MLS_WELCOME",
|
|
MLS_INVALID_COMMIT_WELCOME: 31,
|
|
31: "MLS_INVALID_COMMIT_WELCOME",
|
|
CLIENT_CANNOT_REACH_RTC_SERVER: 32,
|
|
32: "CLIENT_CANNOT_REACH_RTC_SERVER"
|
|
};
|
|
c8870_9 = {
|
|
AUTHENTICATION_FAILED: 4004,
|
|
4004: "AUTHENTICATION_FAILED",
|
|
INVALID_SESSION: 4006,
|
|
4006: "INVALID_SESSION",
|
|
SERVER_NOT_FOUND: 4011,
|
|
4011: "SERVER_NOT_FOUND",
|
|
SERVER_CRASH: 4015,
|
|
4015: "SERVER_CRASH",
|
|
CANCELED: 4016,
|
|
4016: "CANCELED",
|
|
HEARTBEAT_TIMEOUT: 4800,
|
|
4800: "HEARTBEAT_TIMEOUT",
|
|
UNRESUMABLE: 4801,
|
|
4801: "UNRESUMABLE",
|
|
RESET_BACKOFF: 4802,
|
|
4802: "RESET_BACKOFF"
|
|
};
|
|
c8870_10 = {
|
|
DISCONNECTED: 0,
|
|
0: "DISCONNECTED",
|
|
CONNECTING: 1,
|
|
1: "CONNECTING",
|
|
IDENTIFYING: 2,
|
|
2: "IDENTIFYING",
|
|
RESUMING: 3,
|
|
3: "RESUMING",
|
|
CONNECTED: 4,
|
|
4: "CONNECTED",
|
|
RECONNECTING: 5,
|
|
5: "RECONNECTING"
|
|
};
|
|
c8870_11 = 20 * Durations.Millis.SECOND;
|
|
c8870_12 = 1 * Durations.Millis.MINUTE;
|
|
c8870_13 = 5 * Durations.Millis.SECOND;
|
|
c8870_14 = {
|
|
Connecting: "connecting",
|
|
Connect: "connect",
|
|
Disconnect: "disconnect",
|
|
Resuming: "resuming",
|
|
Ready: "ready",
|
|
Speaking: "speaking",
|
|
Video: "video",
|
|
Ping: "ping",
|
|
ClientConnect: "client-connect",
|
|
ClientDisconnect: "client-disconnect",
|
|
Codecs: "codecs",
|
|
MediaSessionId: "media-session-id",
|
|
MediaSinkWants: "media-sink-wants",
|
|
VoiceBackendVersion: "voice-backend-version",
|
|
KeyframeInterval: "keyframe-interval",
|
|
ChannelOptionsUpdateSecureFramesProtocol: "update-secure-frames-protocol",
|
|
Flags: "flags",
|
|
Platform: "platform",
|
|
SDP: "sdp",
|
|
Encryption: "encryption",
|
|
BandwidthEstimationExperiment: "bandwidth-estimation-experiment",
|
|
SecureFramesInit: "secure-frames-init",
|
|
SecureFramesPrepareTransition: "secure-frames-prepare-transition",
|
|
SecureFramesExecuteTransition: "secure-frames-execute-transition",
|
|
SecureFramesPrepareEpoch: "secure-frames-prepare-epoch",
|
|
MLSExternalSenderPackage: "mls-external-sender-package",
|
|
MLSProposals: "mls-proposals",
|
|
MLSPrepareCommitTransition: "mls-prepare-commit-transition",
|
|
MLSWelcome: "mls-welcome",
|
|
ReceiveMessage: "receive-message",
|
|
SendMessage: "send-message"
|
|
};
|
|
class RTCControlSocket extends TypedEventEmitter {
|
|
constructor(a0, r10 = MediaEngineContextTypes.DEFAULT) {
|
|
super();
|
|
this.backoff = new Backoff(1000, 5000);
|
|
this.serverVersion = 0;
|
|
this.url = a0;
|
|
this.logger = new Logger(`RTCControlSocket(${r10})`);
|
|
this.logger.enableNativeLogger(true);
|
|
this.webSocket = null;
|
|
this.connectionState = c8870_10.DISCONNECTED;
|
|
this.helloTimeout = null;
|
|
this.lastHeartbeatAckTime = null;
|
|
this.heartbeatInterval = null;
|
|
this.heartbeater = null;
|
|
this.heartbeatAck = true;
|
|
this.expeditedHeartbeatTimeout = null;
|
|
this.heartbeatIntervalModifier = 1;
|
|
this.connectionStartTime = 0;
|
|
this.lastRecvSeqNum = null;
|
|
this.sessionId = null;
|
|
this.serverId = null;
|
|
this.channelId = null;
|
|
this.token = null;
|
|
this.resumable = false;
|
|
}
|
|
createWebSocket() {
|
|
this.logger.info(`[CONNECT] ${this.url}`);
|
|
if (this.webSocket !== null) {
|
|
this.logger.error("Connect called with already existing websocket");
|
|
this.cleanupWebSocket((a0) => a0.close(4000));
|
|
}
|
|
this.connectionStartTime = now();
|
|
this.helloTimeout = setTimeout(() => {
|
|
const r13 = now();
|
|
this.handleClose(false, 0, `The connection timed out after ${r13 - this.connectionStartTime} ms - did not receive OP_HELLO in time.`);
|
|
}, c8870_11);
|
|
const webSocket = new WebSocket(`${this.url}?v=9`);
|
|
this.webSocket = webSocket;
|
|
webSocket.binaryType = "arraybuffer";
|
|
webSocket.onopen = () => {
|
|
const connectionState = this.connectionState;
|
|
if (connectionState === c8870_10.CONNECTING) {
|
|
this.emit(c8870_14.Connect);
|
|
} else if (this.connectionState === c8870_10.RECONNECTING) {
|
|
this.doResumeOrClose();
|
|
}
|
|
this.connectionState = c8870_10.CONNECTED;
|
|
const r7 = now() - this.connectionStartTime;
|
|
this.logger.info(`[CONNECTED] ${this.url} in ${r7} ms`);
|
|
this.emit(c8870_14.Ping, Math.round(r7 / 2));
|
|
};
|
|
webSocket.onmessage = (a0) => {
|
|
const r25 = this.parseWebSocketMessage(a0);
|
|
const { op, seq, d: r26 } = r25;
|
|
const r9 = env8870;
|
|
this.emit(c8870_14.ReceiveMessage, op, r26);
|
|
if (seq) {
|
|
this.lastRecvSeqNum = seq;
|
|
}
|
|
if (DeveloperOptionsStore.isLoggingGatewayEvents) {
|
|
if (r26 instanceof Uint8Array) {
|
|
this.logger.info(`~> ${op}: 0x${[...r26].map((item) => item.toString(16).padStart(2, "0")).join("")}`);
|
|
} else {
|
|
this.logger.info(`~> ${op}: ${JSON.stringify(r26)}`);
|
|
}
|
|
}
|
|
if (c8870_8.HELLO === op) {
|
|
this.clearHelloTimeout();
|
|
this.handleHello(r26);
|
|
} else if (c8870_8.READY === op) {
|
|
this.handleReady(r26);
|
|
} else if (c8870_8.RESUMED === op) {
|
|
this.handleResumed(r26);
|
|
} else if (c8870_8.SELECT_PROTOCOL_ACK === op) {
|
|
if (r26.bandwidth_estimation_experiment) {
|
|
this.emit(c8870_14.BandwidthEstimationExperiment, r26.bandwidth_estimation_experiment);
|
|
}
|
|
this.emit(c8870_14.Codecs, r26.audio_codec, r26.video_codec);
|
|
if (r26.media_session_id) {
|
|
this.emit(c8870_14.MediaSessionId, r26.media_session_id);
|
|
}
|
|
if (r26.sdp) {
|
|
this.emit(c8870_14.SDP, r26.sdp);
|
|
} else if (r26.mode) {
|
|
this.emit(c8870_14.Encryption, r26.mode, r26.secret_key);
|
|
}
|
|
if (r26.keyframe_interval) {
|
|
this.emit(c8870_14.KeyframeInterval, r26.keyframe_interval);
|
|
}
|
|
this.emit(c8870_14.SecureFramesInit, r26.dave_protocol_version || 0);
|
|
this.resumable = true;
|
|
} else if (c8870_8.SPEAKING === op) {
|
|
const speaking2 = r26.speaking;
|
|
let r229 = speaking2;
|
|
if (typeof r229 === "boolean") {
|
|
r229 = speaking2 ? SpeakingFlags.VOICE : SpeakingFlags.NONE;
|
|
}
|
|
this.emit(c8870_14.Speaking, r26.user_id, r26.ssrc, r229);
|
|
} else if (c8870_8.HEARTBEAT === op) {
|
|
this.sendHeartbeat();
|
|
} else if (c8870_8.HEARTBEAT_ACK === op) {
|
|
this.handleHeartbeatAck(r26);
|
|
} else if (c8870_8.VIDEO === op) {
|
|
const Video = c8870_14.Video;
|
|
const { user_id, audio_ssrc, video_ssrc, streams } = r26;
|
|
let r216 = streams == null ? void 0 : streams.map($mk90530(r9));
|
|
if (r216 == null) {
|
|
r216 = [];
|
|
}
|
|
this.emit(Video, user_id, audio_ssrc, video_ssrc, r216);
|
|
} else if (c8870_8.CLIENT_CONNECT === op) {
|
|
this.emit(c8870_14.ClientConnect, r26.user_ids);
|
|
} else if (c8870_8.CLIENT_DISCONNECT === op) {
|
|
this.emit(c8870_14.ClientDisconnect, r26.user_id);
|
|
} else if (c8870_8.SESSION_UPDATE === op) {
|
|
if (!(r26.audio_codec == null && r26.video_codec == null)) {
|
|
this.emit(c8870_14.Codecs, r26.audio_codec, r26.video_codec);
|
|
}
|
|
if (r26.media_session_id != null) {
|
|
this.emit(c8870_14.MediaSessionId, r26.media_session_id);
|
|
}
|
|
if (r26.keyframe_interval) {
|
|
this.emit(c8870_14.KeyframeInterval, r26.keyframe_interval);
|
|
}
|
|
} else if (c8870_8.MEDIA_SINK_WANTS === op) {
|
|
this.emit(c8870_14.MediaSinkWants, r26);
|
|
} else if (c8870_8.VOICE_BACKEND_VERSION === op) {
|
|
if (r26.voice != null && r26.rtc_worker != null) {
|
|
this.emit(c8870_14.VoiceBackendVersion, r26.voice, r26.rtc_worker);
|
|
}
|
|
} else if (c8870_8.FLAGS === op) {
|
|
if (r26.flags != null && r26.user_id != null) {
|
|
this.emit(c8870_14.Flags, r26.user_id, r26.flags);
|
|
}
|
|
} else if (c8870_8.PLATFORM === op) {
|
|
if (r26.platform != null && r26.user_id != null) {
|
|
this.emit(c8870_14.Platform, r26.user_id, r26.platform);
|
|
}
|
|
} else if (c8870_8.DAVE_PROTOCOL_PREPARE_TRANSITION === op) {
|
|
if (r26.transition_id != null && r26.protocol_version != null) {
|
|
this.emit(c8870_14.SecureFramesPrepareTransition, r26.transition_id, r26.protocol_version);
|
|
}
|
|
} else if (c8870_8.DAVE_PROTOCOL_EXECUTE_TRANSITION === op) {
|
|
if (r26.transition_id != null) {
|
|
this.emit(c8870_14.SecureFramesExecuteTransition, r26.transition_id);
|
|
}
|
|
} else if (c8870_8.DAVE_PROTOCOL_PREPARE_EPOCH === op) {
|
|
if (r26.epoch != null && r26.protocol_version != null) {
|
|
this.emit(c8870_14.SecureFramesPrepareEpoch, r26.epoch, r26.protocol_version);
|
|
}
|
|
} else if (c8870_8.MLS_EXTERNAL_SENDER_PACKAGE === op) {
|
|
this.emit(c8870_14.MLSExternalSenderPackage, r26);
|
|
} else if (c8870_8.MLS_PROPOSALS === op) {
|
|
this.emit(c8870_14.MLSProposals, r26);
|
|
} else if (c8870_8.MLS_PREPARE_COMMIT_TRANSITION === op) {
|
|
this.emit(c8870_14.MLSPrepareCommitTransition, new DataView(r26.buffer, r26.byteOffset, 2).getUint16(0, false), r26.slice(2));
|
|
} else if (c8870_8.MLS_WELCOME === op) {
|
|
this.emit(c8870_14.MLSWelcome, new DataView(r26.buffer, r26.byteOffset, 2).getUint16(0, false), r26.slice(2));
|
|
} else {
|
|
this.logger.info(`Unhandled op ${op}`);
|
|
}
|
|
};
|
|
webSocket.onerror = () => this.handleClose(false, 0, "An error with the websocket occurred");
|
|
webSocket.onclose = (a0) => this.handleClose(a0.wasClean, a0.code, a0.reason);
|
|
}
|
|
send(a0, r7 = null) {
|
|
const webSocket = this.webSocket;
|
|
if (webSocket != null && webSocket.readyState === WebSocket.OPEN) {
|
|
const r15 = JSON.stringify({
|
|
op: a0,
|
|
d: r7
|
|
});
|
|
if (DeveloperOptionsStore.isLoggingGatewayEvents) {
|
|
this.logger.info(`<~ ${r15}`);
|
|
}
|
|
this.emit(c8870_14.SendMessage, a0, r7);
|
|
try {
|
|
webSocket.send(r15);
|
|
} catch ($e) {}
|
|
}
|
|
}
|
|
sendBinary(a0, a1) {
|
|
const webSocket = this.webSocket;
|
|
if (webSocket != null && webSocket.readyState === WebSocket.OPEN) {
|
|
const uint8Array = new Uint8Array(a1.byteLength + 1);
|
|
uint8Array[0] = a0;
|
|
uint8Array.set(a1, 1);
|
|
try {
|
|
webSocket.send(uint8Array.buffer);
|
|
} catch ($e) {}
|
|
}
|
|
}
|
|
doResumeOrClose() {
|
|
L9: {
|
|
L7: {
|
|
const lastHeartbeatAckTime = now();
|
|
if (this.serverId !== null && this.channelId !== null && this.token !== null && this.sessionId !== null && this.resumable) {
|
|
if (this.lastHeartbeatAckTime != null && !(lastHeartbeatAckTime - this.lastHeartbeatAckTime <= c8870_12)) {
|
|
break L7;
|
|
}
|
|
this.doResume();
|
|
this.lastHeartbeatAckTime = lastHeartbeatAckTime;
|
|
break L9;
|
|
}
|
|
}
|
|
this.disconnect(false, c8870_9.UNRESUMABLE, "Cannot resume connection.");
|
|
}
|
|
}
|
|
doResume() {
|
|
let lastRecvSeqNum = this.lastRecvSeqNum;
|
|
if (lastRecvSeqNum == null) {
|
|
lastRecvSeqNum = -1;
|
|
}
|
|
const logger = this.logger;
|
|
let serverId = this.serverId;
|
|
if (serverId == null) {
|
|
serverId = "";
|
|
}
|
|
let channelId = this.channelId;
|
|
if (channelId == null) {
|
|
channelId = "";
|
|
}
|
|
let sessionId = this.sessionId;
|
|
if (sessionId == null) {
|
|
sessionId = "";
|
|
}
|
|
logger.info(`[RESUME] resuming session. serverId=${serverId} channelId=${channelId} sessionId=${sessionId} seqAck=${lastRecvSeqNum}`);
|
|
this.emit(c8870_14.Resuming);
|
|
this.connectionState = c8870_10.RESUMING;
|
|
this.send(c8870_8.RESUME, {
|
|
token: this.token,
|
|
session_id: this.sessionId,
|
|
server_id: this.serverId,
|
|
channel_id: this.channelId,
|
|
seq_ack: lastRecvSeqNum
|
|
});
|
|
}
|
|
handleHello(a0) {
|
|
let r27, r28;
|
|
let serverVersion = a0.v;
|
|
if (serverVersion == null) {
|
|
serverVersion = 3;
|
|
}
|
|
this.serverVersion = serverVersion;
|
|
if (this.serverVersion <= 3) {
|
|
this.heartbeatInterval = a0.heartbeat_interval * (isPlatformEmbedded ? 0.25 : 0.1);
|
|
r27 = dependencyMap;
|
|
r28 = require;
|
|
} else {
|
|
this.heartbeatInterval = a0.heartbeat_interval * this.heartbeatIntervalModifier;
|
|
r27 = dependencyMap;
|
|
r28 = require;
|
|
if (!isPlatformEmbedded) {
|
|
const r13 = Math;
|
|
let heartbeatInterval = this.heartbeatInterval;
|
|
if (heartbeatInterval == null) {
|
|
heartbeatInterval = NaN;
|
|
}
|
|
this.heartbeatInterval = r13.min(c8870_13, heartbeatInterval);
|
|
r27 = dependencyMap;
|
|
r28 = require;
|
|
}
|
|
}
|
|
const r14 = r28(r27[6]).now() - this.connectionStartTime;
|
|
const logger = this.logger;
|
|
let heartbeatInterval2 = this.heartbeatInterval;
|
|
if (heartbeatInterval2 == null) {
|
|
heartbeatInterval2 = "??";
|
|
}
|
|
logger.info(`[HELLO] heartbeat interval: ${heartbeatInterval2}, version: ${this.serverVersion}, took ${r14} ms`);
|
|
this.startHeartbeater();
|
|
}
|
|
handleReady(a0) {
|
|
const r13 = env8870;
|
|
this.backoff.succeed();
|
|
this.logger.info(`[READY] took ${now() - this.connectionStartTime} ms`);
|
|
if (this.serverVersion >= 6) {
|
|
this.send(c8870_8.VOICE_BACKEND_VERSION, {});
|
|
}
|
|
const emit = this.emit;
|
|
const Ready = c8870_14.Ready;
|
|
const { ip, port, modes, ssrc, streams } = a0;
|
|
let r50 = streams == null ? void 0 : streams.map($mk90530(r13));
|
|
if (r50 == null) {
|
|
r50 = [];
|
|
}
|
|
emit.call(this, Ready, ip, port, modes, ssrc, r50, a0.experiments);
|
|
}
|
|
handleResumed() {
|
|
this.backoff.succeed();
|
|
}
|
|
handleClose(a0, a1, a2) {
|
|
let r6 = a0;
|
|
let c20272_1 = a0;
|
|
this.connectionState = c8870_10.DISCONNECTED;
|
|
if (!a0) {
|
|
r6 = false;
|
|
}
|
|
c20272_1 = r6;
|
|
this.cleanupWebSocket();
|
|
if (a1 !== c8870_9.AUTHENTICATION_FAILED && a1 !== c8870_9.SERVER_CRASH && a1 !== c8870_9.SERVER_NOT_FOUND && a1 !== c8870_9.INVALID_SESSION) {
|
|
if (this.backoff.fails > 3) {
|
|
this.logger.warn("[WS CLOSED] Backoff exceed. Resetting.");
|
|
this.disconnect(r6, a1, a2);
|
|
} else {
|
|
const r39 = this.backoff.fail(() => this.reconnect(c20272_1, a1, a2));
|
|
this.logger.warn(`[WS CLOSED] (clean: ${r6.toString()}, code: ${a1}, reason: ${a2}) retrying in ${(r39 / 1000).toFixed(2)} seconds.`);
|
|
}
|
|
return void 0;
|
|
}
|
|
return this.disconnect(r6, a1, a2);
|
|
}
|
|
disconnect(a0, a1, a2) {
|
|
this.logger.warn(`[DISCONNECT] (${a0.toString()}, ${a1}, ${a2})`);
|
|
this.cleanupWebSocket();
|
|
this.cleanupState();
|
|
this.connectionState = c8870_10.DISCONNECTED;
|
|
this.emit(c8870_14.Disconnect, a0, a1, a2);
|
|
}
|
|
reconnect(a0, a1, a2) {
|
|
this.logger.info(`[RECONNECT] wasClean=${a0.toString()} code=${a1} reason=${a2}`);
|
|
this.cleanupWebSocket((a0) => a0.close(4000));
|
|
this.connectionState = c8870_10.RECONNECTING;
|
|
this.createWebSocket();
|
|
}
|
|
cleanupWebSocket(a0) {
|
|
this.stopHeartbeater();
|
|
this.clearHelloTimeout();
|
|
const webSocket = this.webSocket;
|
|
this.webSocket = null;
|
|
if (webSocket != null) {
|
|
webSocket.onopen = noop;
|
|
webSocket.onmessage = noop;
|
|
webSocket.onerror = noop;
|
|
webSocket.onclose = noop;
|
|
if (a0 != null) {
|
|
a0(webSocket);
|
|
}
|
|
}
|
|
this.backoff.cancel();
|
|
}
|
|
cleanupState() {
|
|
this.serverId = null;
|
|
this.channelId = null;
|
|
this.sessionId = null;
|
|
this.token = null;
|
|
this.resumable = false;
|
|
this.lastRecvSeqNum = null;
|
|
}
|
|
parseWebSocketMessage(a0) {
|
|
if (a0.data instanceof ArrayBuffer) {
|
|
const uint8Array = new Uint8Array(a0.data);
|
|
const seq = this.serverVersion >= 8 ? new DataView(uint8Array.buffer).getUint16(0, false) : null;
|
|
const r32 = this.serverVersion >= 8 ? 2 : 0;
|
|
return {
|
|
op: uint8Array[r32],
|
|
seq,
|
|
d: uint8Array.subarray(r32 + 1)
|
|
};
|
|
}
|
|
return JSON.parse(a0.data);
|
|
}
|
|
clearHelloTimeout() {
|
|
if (this.helloTimeout != null) {
|
|
clearTimeout(this.helloTimeout);
|
|
this.helloTimeout = null;
|
|
}
|
|
}
|
|
handleHeartbeatAck(a0) {
|
|
this.logger.info("Heartbeat ACK received");
|
|
const r9 = this.serverVersion >= 8 ? a0.t : a0;
|
|
this.emit(c8870_14.Ping, now() - r9);
|
|
this.lastHeartbeatAckTime = now();
|
|
this.heartbeatAck = true;
|
|
if (this.expeditedHeartbeatTimeout !== null) {
|
|
clearTimeout(this.expeditedHeartbeatTimeout);
|
|
this.expeditedHeartbeatTimeout = null;
|
|
this.logger.info("Expedited heartbeat succeeded");
|
|
}
|
|
}
|
|
handleHeartbeatTimeout() {
|
|
this.cleanupWebSocket((a0) => a0.close(4000));
|
|
this.logger.warn(`[HEARTBEAT ACK TIMEOUT] reconnecting in ${(this.backoff.fail(() => this.reconnect(false, c8870_9.HEARTBEAT_TIMEOUT, "Heartbeat timeout.")) / 1000).toFixed(2)} seconds.`);
|
|
}
|
|
startHeartbeater() {
|
|
Module38(this.heartbeatInterval != null, "RTCControlSocket: Heartbeat interval should never null here.");
|
|
this.logger.info(`Starting heartbeat with interval: ${this.heartbeatInterval}`);
|
|
if (this.heartbeater !== null) {
|
|
clearInterval(this.heartbeater);
|
|
}
|
|
this.heartbeatAck = true;
|
|
this.heartbeater = setInterval(() => {
|
|
if (this.heartbeatAck) {
|
|
this.heartbeatAck = false;
|
|
this.sendHeartbeat();
|
|
} else if (this.expeditedHeartbeatTimeout === null) {
|
|
this.handleHeartbeatTimeout();
|
|
}
|
|
}, this.heartbeatInterval);
|
|
}
|
|
sendHeartbeat() {
|
|
if (this.serverVersion >= 8) {
|
|
let lastRecvSeqNum = this.lastRecvSeqNum;
|
|
if (lastRecvSeqNum == null) {
|
|
lastRecvSeqNum = -1;
|
|
}
|
|
this.logger.info(`Sending heartbeat with last received sequence number: ${lastRecvSeqNum}`);
|
|
this.send(c8870_8.HEARTBEAT, {
|
|
t: now(),
|
|
seq_ack: lastRecvSeqNum
|
|
});
|
|
} else {
|
|
this.logger.info("Sending heartbeat");
|
|
this.send(c8870_8.HEARTBEAT, now());
|
|
}
|
|
}
|
|
stopHeartbeater() {
|
|
if (this.heartbeater !== null) {
|
|
clearInterval(this.heartbeater);
|
|
this.heartbeater = null;
|
|
}
|
|
if (this.expeditedHeartbeatTimeout !== null) {
|
|
clearTimeout(this.expeditedHeartbeatTimeout);
|
|
this.expeditedHeartbeatTimeout = null;
|
|
}
|
|
}
|
|
connect() {
|
|
let r0;
|
|
const connectionState = this.connectionState;
|
|
if (connectionState !== c8870_10.DISCONNECTED) {
|
|
this.logger.error("Cannot start a new connection, connection state is not disconnected");
|
|
r0 = false;
|
|
} else {
|
|
this.connectionState = c8870_10.CONNECTING;
|
|
this.createWebSocket();
|
|
this.emit(c8870_14.Connecting);
|
|
r0 = true;
|
|
}
|
|
return r0;
|
|
}
|
|
identify({ serverId, channelId, userId, sessionId, token, maxDaveProtocolVersion, video: video2 = false, streamParameters }) {
|
|
this.serverId = serverId;
|
|
this.channelId = channelId;
|
|
this.sessionId = sessionId;
|
|
this.token = token;
|
|
this.connectionState = c8870_10.IDENTIFYING;
|
|
this.send(c8870_8.IDENTIFY, {
|
|
server_id: serverId,
|
|
channel_id: channelId,
|
|
user_id: userId,
|
|
session_id: sessionId,
|
|
token,
|
|
max_dave_protocol_version: maxDaveProtocolVersion,
|
|
video: video2,
|
|
streams: streamParameters == null ? void 0 : streamParameters.map($mk90529())
|
|
});
|
|
}
|
|
expeditedHeartbeat(a0, r9 = "", r5 = true) {
|
|
if (this.webSocket != null) {
|
|
this.logger.info("Performing an expedited heartbeat " + (r9 !== "" ? "reason: " + r9 : ""));
|
|
this.heartbeatAck = false;
|
|
this.sendHeartbeat();
|
|
if (this.expeditedHeartbeatTimeout !== null) {
|
|
clearTimeout(this.expeditedHeartbeatTimeout);
|
|
}
|
|
this.expeditedHeartbeatTimeout = setTimeout(() => {
|
|
this.expeditedHeartbeatTimeout = null;
|
|
if (this.heartbeatAck === false) {
|
|
this.handleHeartbeatTimeout();
|
|
}
|
|
}, a0);
|
|
} else {
|
|
if (r5) {
|
|
return this.resetBackoff(r9);
|
|
}
|
|
this.logger.info("Expedited heartbeat requested, but is disconnected and a reset was not requested " + (r9 !== "" ? "reason: " + r9 : ""));
|
|
}
|
|
return false;
|
|
}
|
|
resetBackoff(r4 = "") {
|
|
let r10 = this.backoff.fails > 0 && this.webSocket == null;
|
|
if (r10) {
|
|
this.logger.info("Connection backoff reset " + (r4 !== "" ? "for reason: " + r4 : ""));
|
|
this.backoff.succeed();
|
|
this.reconnect(false, c8870_9.RESET_BACKOFF, "Reset backoff.");
|
|
r10 = true;
|
|
}
|
|
return r10;
|
|
}
|
|
close() {
|
|
this.logger.info("CLOSE");
|
|
this.cleanupWebSocket((a0) => a0.close(4000));
|
|
this.cleanupState();
|
|
this.connectionState = c8870_10.DISCONNECTED;
|
|
this.emit(c8870_14.Disconnect, true, 1000, "Force Close");
|
|
}
|
|
destroy() {
|
|
this.close();
|
|
}
|
|
selectProtocol(a0, a1, a2, a3) {
|
|
let r6, data;
|
|
L17: {
|
|
const r3 = {};
|
|
const r1 = a2 == null;
|
|
r6 = r3;
|
|
data = null;
|
|
if (!r1) {
|
|
if ("sdp" in a2 && a2.sdp != null && a2.sdp !== "") {
|
|
data = a2.sdp;
|
|
r6 = {
|
|
...a2,
|
|
codecs: a2.codecs.map($mk90528()),
|
|
rtc_connection_id: a1
|
|
};
|
|
break L17;
|
|
}
|
|
const r18 = "address" in a2 && a2.address != null && a2.address !== "" && Boolean(a2.port) && a2.mode != null && a2.mode !== "";
|
|
r6 = r3;
|
|
data = void 0;
|
|
if (r18) {
|
|
const r31 = {
|
|
address: a2.address,
|
|
port: a2.port,
|
|
mode: a2.mode
|
|
};
|
|
r6 = {
|
|
...a2,
|
|
codecs: a2.codecs.map($mk90528()),
|
|
rtc_connection_id: a1,
|
|
experiments: a3
|
|
};
|
|
data = r31;
|
|
}
|
|
}
|
|
}
|
|
this.send(c8870_8.SELECT_PROTOCOL, {
|
|
protocol: a0,
|
|
data,
|
|
...r6
|
|
});
|
|
}
|
|
updateSession(a0) {
|
|
this.send(c8870_8.SESSION_UPDATE, {
|
|
codecs: a0.codecs.map($mk90528())
|
|
});
|
|
}
|
|
speaking(a0, delay = 0, ssrc = 0) {
|
|
this.send(c8870_8.SPEAKING, {
|
|
speaking: this.serverVersion <= 3 ? Boolean(a0) : a0,
|
|
delay,
|
|
ssrc
|
|
});
|
|
}
|
|
video(a0, a1, a2, a3) {
|
|
this.send(c8870_8.VIDEO, {
|
|
audio_ssrc: a0,
|
|
video_ssrc: a1,
|
|
rtx_ssrc: a2,
|
|
streams: a3 == null ? void 0 : a3.map($mk90529())
|
|
});
|
|
}
|
|
mediaSinkWants(a0) {
|
|
if (this.serverVersion >= 5) {
|
|
this.send(c8870_8.MEDIA_SINK_WANTS, a0);
|
|
}
|
|
}
|
|
secureFramesReadyForTransition(a0) {
|
|
this.send(c8870_8.DAVE_PROTOCOL_READY_FOR_TRANSITION, {
|
|
transition_id: a0
|
|
});
|
|
}
|
|
sendMLSKeyPackage(a0) {
|
|
this.logger.info("Sending MLS key package");
|
|
this.sendBinary(c8870_8.MLS_KEY_PACKAGE, new Uint8Array(a0));
|
|
}
|
|
sendMLSCommitWelcome(a0) {
|
|
this.logger.info("Sending MLS commit + welcome message");
|
|
this.sendBinary(c8870_8.MLS_COMMIT_WELCOME, new Uint8Array(a0));
|
|
}
|
|
flagMLSInvalidCommitWelcome(a0) {
|
|
this.send(c8870_8.MLS_INVALID_COMMIT_WELCOME, {
|
|
transition_id: a0
|
|
});
|
|
}
|
|
noRoute() {
|
|
this.send(c8870_8.CLIENT_CANNOT_REACH_RTC_SERVER, {});
|
|
}
|
|
setHeartbeatIntervalModifier(a0) {
|
|
this.heartbeatIntervalModifier = a0;
|
|
}
|
|
}
|
|
c8870_15 = RTCControlSocket;
|
|
export default RTCControlSocket;
|
|
export { c8870_8 as RTCSocketOpcode };
|
|
export { c8870_14 as SocketEvent };
|