decord/stable/source/lib/RTCControlSocket.tsx
2026-10-06 22:12:49 +00:00

922 lines
34 KiB
TypeScript

// Module ID: 1998
// Function ID: 1999
// Name: RTCControlSocket
// Dependencies: [1358, 1999, 4862, 1103, 4895, 569, 3, 4866, 13623, 1370, 38, 2]
// Module 1998 (RTCControlSocket)
import LoggerDefault from "Logger" /* 3 */;
import _modDef38 from "module_38" /* 38 */;
import BackoffDefault from "Backoff" /* 569 */;
import DurationsDefault from "Durations" /* 1103 */;
import PlatformUtils from "PlatformUtils" /* 1370 */;
import TimeUtils from "TimeUtils" /* 4866 */;
import DeveloperOptionsStore from "DeveloperOptionsStore" /* 1358 */;
import MediaEngineStore from "MediaEngineStore" /* 1999 */;
import Constants from "Constants" /* 4862 */;
import TypedEventEmitter from "TypedEventEmitter" /* 4895 */;
import size_mod from "module_2" /* 2 */;
let hasOwnProperty;
let metroImportAll;
let metroImportDefault;
let metroRequire;
const f84373 = (name) => ({ name: name.name, type: name.type, priority: 1000 * name.priority, payload_type: name.payloadType, rtx_payload_type: name.rtxPayloadType, encode: name.encode, decode: name.decode });
const f84374 = (type) => {
let tmp;
const obj = { type: type.type, rid: type.rid, ssrc: type.ssrc, active: type.active, quality: type.quality, rtx_ssrc: type.rtxSsrc, max_bitrate: type.maxBitrate, max_framerate: type.maxFrameRate, max_resolution: tmp };
tmp = undefined;
if (null != type.maxResolution) {
size = { type: type.maxResolution.type, width: type.maxResolution.width, height: type.maxResolution.height };
tmp = size;
}
return obj;
};
const f84375 = (rid) => {
let VIDEO;
let tmp5;
const type = rid.type;
if ("audio" === type) {
VIDEO = constants.AUDIO;
} else if ("test" === type) {
VIDEO = constants.TEST;
} else if ("screen" === type) {
VIDEO = constants.SCREEN;
} else {
VIDEO = constants.VIDEO;
}
const obj = { type: VIDEO, rid: rid.rid, ssrc: rid.ssrc, rtxSsrc: rid.rtx_ssrc, active: rid.active, quality: rid.quality, maxBitrate: rid.max_bitrate, maxFrameRate: rid.max_framerate, maxResolution: tmp5 };
tmp5 = undefined;
if (null != rid.max_resolution) {
size = { type: rid.max_resolution.type, width: rid.max_resolution.width, height: rid.max_resolution.height };
tmp5 = size;
}
return obj;
};
function noop() {
}
({ Features: hasOwnProperty, MediaEngineContextTypes: metroRequire, MediaTypes: metroImportDefault, SpeakingFlags: metroImportAll } = Constants);
const RTCSocketOpcode = { 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", SFU_UPDATE: 33, [33]: "SFU_UPDATE" };
let obj2 = { 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", REPEATED_MLS_INVALID_MESSAGES: 4803, [4803]: "REPEATED_MLS_INVALID_MESSAGES", DAVE_DOWNGRADE_REFUSED: 4804, [4804]: "DAVE_DOWNGRADE_REFUSED" };
const constants3 = { DISCONNECTED: 0, [0]: "DISCONNECTED", CONNECTING: 1, [1]: "CONNECTING", IDENTIFYING: 2, [2]: "IDENTIFYING", RESUMING: 3, [3]: "RESUMING", CONNECTED: 4, [4]: "CONNECTED", RECONNECTING: 5, [5]: "RECONNECTING" };
let closure_13 = 20 * DurationsDefault.Millis.SECOND;
const MINUTE = DurationsDefault.Millis.MINUTE;
let closure_15 = 5 * DurationsDefault.Millis.SECOND;
let obj3 = { Connecting: "connecting", Connect: "connect", Disconnect: "disconnect", Resuming: "resuming", Ready: "ready", SfuUpdate: "sfu-update", 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(url, DEFAULT) {
if (DEFAULT === undefined) {
DEFAULT = metroRequire.DEFAULT;
}
const tmp6 = new RTCControlSocket(tmp4, tmp3, tmp2, DEFAULT, tmp, url);
tmp6.backoff = new BackoffDefault(1000, 5000);
tmp6.serverVersion = 0;
tmp6.url = url;
new BackoffDefault(1000, 5000);
const tmp8 = LoggerDefault;
tmp6.logger = new tmp8("RTCControlSocket(" + DEFAULT + ")");
const logger = tmp6.logger;
new tmp8("RTCControlSocket(" + DEFAULT + ")");
logger.enableNativeLogger(true);
tmp6.webSocket = null;
tmp6.connectionState = constants3.DISCONNECTED;
tmp6.helloTimeout = null;
tmp6.lastHeartbeatAckTime = null;
tmp6.heartbeatInterval = null;
tmp6.heartbeater = null;
tmp6.heartbeatAck = true;
tmp6.expeditedHeartbeatTimeout = null;
tmp6.heartbeatIntervalModifier = 1;
tmp6.connectionStartTime = 0;
tmp6.lastRecvSeqNum = null;
tmp6.sessionId = null;
tmp6.serverId = null;
tmp6.channelId = null;
tmp6.token = null;
tmp6.resumable = false;
return tmp6;
}
createWebSocket() {
let self = this;
let logger = this.logger;
logger.info("[CONNECT] " + this.url);
if (null !== this.webSocket) {
let logger2 = self.logger;
let str = "Connect called with already existing websocket";
logger2.error("Connect called with already existing websocket");
self.cleanupWebSocket((close) => close.close(4000));
}
let obj = self(4866);
self.connectionStartTime = obj.now();
self.helloTimeout = setTimeout(() => {
const obj = TimeUtils;
self.handleClose(false, 0, "The connection timed out after " + obj.now() - self.connectionStartTime + " ms - did not receive OP_HELLO in time.");
}, closure_13);
obj2 = self(13623);
obj3 = { location: "RTCControlSocket", supportsSfuUpdate: MediaEngineStore.supports(constants.UDP_ENDPOINT_UPDATE) };
const webSocket = new WebSocket("" + self.url + "?v=" + obj2.getVoiceGatewayProtocolVersion(obj3));
self.webSocket = webSocket;
webSocket.binaryType = "arraybuffer";
webSocket.onopen = () => {
if (self.connectionState === constants.CONNECTING) {
self.emit(obj3.Connect);
} else if (self.connectionState === constants.RECONNECTING) {
self.doResumeOrClose();
}
self.connectionState = constants.CONNECTED;
obj2 = TimeUtils;
const diff = obj2.now() - obj.connectionStartTime;
const logger = obj.logger;
logger.info("[CONNECTED] " + self.url + " in " + diff + " ms");
self.emit(obj3.Ping, Math.round(diff / 2));
};
webSocket.onmessage = function(data) {
let audio_ssrc;
let d;
let op;
let seq;
let streams;
let user_id;
let video_ssrc;
let obj = self;
const result = self.parseWebSocketMessage(data);
({ op, seq, d } = result);
self.emit(obj3.ReceiveMessage, op, d);
if (seq) {
obj.lastRecvSeqNum = seq;
}
if (DeveloperOptionsStore.isLoggingGatewayEvents) {
let tmp5 = globalThis;
const _Uint8Array = Uint8Array;
if (d instanceof Uint8Array) {
const items = [];
HermesBuiltin.arraySpread(items, d, 0);
const mapped = items.map((item) => {
const str = item.toString(16);
return str.padStart(2, "0");
});
const logger2 = obj.logger;
const _HermesInternal2 = HermesInternal;
logger2.info("~> " + op + ": 0x" + mapped.join(""));
} else {
const logger = obj.logger;
const _JSON = JSON;
const _HermesInternal = HermesInternal;
let str = ": ";
logger.info("~> " + op + ": " + JSON.stringify(d));
}
}
if (obj.HELLO === op) {
obj.clearHelloTimeout();
obj.handleHello(d);
} else if (obj.READY === op) {
obj.handleReady(d);
} else if (obj.SFU_UPDATE === op) {
obj.emit(obj3.SfuUpdate, d);
} else if (obj.RESUMED === op) {
obj.handleResumed(d);
} else if (obj.SELECT_PROTOCOL_ACK === op) {
if (d.bandwidth_estimation_experiment) {
obj.emit(obj3.BandwidthEstimationExperiment, d.bandwidth_estimation_experiment);
}
obj.emit(obj3.Codecs, d.audio_codec, d.video_codec);
if (d.media_session_id) {
obj.emit(obj3.MediaSessionId, d.media_session_id);
}
if (d.sdp) {
obj.emit(obj3.SDP, d.sdp);
} else if (d.mode) {
obj.emit(obj3.Encryption, d.mode, d.secret_key);
}
if (d.keyframe_interval) {
obj.emit(obj3.KeyframeInterval, d.keyframe_interval);
}
let num8 = d.dave_protocol_version;
const emit2 = obj.emit;
const SecureFramesInit = tmp3.SecureFramesInit;
if (!num8) {
num8 = 0;
}
emit2(SecureFramesInit, num8);
obj.resumable = true;
} else if (obj.SPEAKING === op) {
const speaking = d.speaking;
let tmp58 = speaking;
if (typeof speaking === "boolean") {
tmp58 = speaking ? tmp75.VOICE : tmp75.NONE;
}
obj.emit(obj3.Speaking, d.user_id, d.ssrc, tmp58);
} else if (obj.HEARTBEAT === op) {
obj.sendHeartbeat();
} else if (obj.HEARTBEAT_ACK === op) {
obj.handleHeartbeatAck(d);
} else if (obj.VIDEO === op) {
const Video = tmp3.Video;
({ user_id, audio_ssrc, video_ssrc, streams } = d);
let mapped1;
const emit = obj.emit;
if (streams != null) {
mapped1 = streams.map(f84375);
}
if (mapped1 == null) {
mapped1 = [];
}
emit(Video, user_id, audio_ssrc, video_ssrc, mapped1);
} else if (obj.CLIENT_CONNECT === op) {
obj.emit(obj3.ClientConnect, d.user_ids);
} else if (obj.CLIENT_DISCONNECT === op) {
obj.emit(obj3.ClientDisconnect, d.user_id);
} else if (obj.SESSION_UPDATE === op) {
const tmp42 = null == d.audio_codec && null == d.video_codec;
if (!tmp42) {
obj.emit(obj3.Codecs, d.audio_codec, d.video_codec);
}
if (null != d.media_session_id) {
obj.emit(obj3.MediaSessionId, d.media_session_id);
}
if (d.keyframe_interval) {
obj.emit(obj3.KeyframeInterval, d.keyframe_interval);
}
} else if (obj.MEDIA_SINK_WANTS === op) {
obj.emit(obj3.MediaSinkWants, d);
} else if (obj.VOICE_BACKEND_VERSION === op) {
const tmp38 = null != d.voice && null != d.rtc_worker;
if (tmp38) {
obj.emit(obj3.VoiceBackendVersion, d.voice, d.rtc_worker);
}
} else if (obj.FLAGS === op) {
const tmp35 = null != d.flags && null != d.user_id;
if (tmp35) {
obj.emit(obj3.Flags, d.user_id, d.flags);
}
} else if (obj.PLATFORM === op) {
const tmp32 = null != d.platform && null != d.user_id;
if (tmp32) {
obj.emit(obj3.Platform, d.user_id, d.platform);
}
} else if (obj.DAVE_PROTOCOL_PREPARE_TRANSITION === op) {
const tmp29 = null != d.transition_id && null != d.protocol_version;
if (tmp29) {
obj.emit(obj3.SecureFramesPrepareTransition, d.transition_id, d.protocol_version);
}
} else if (obj.DAVE_PROTOCOL_EXECUTE_TRANSITION === op) {
if (null != d.transition_id) {
obj.emit(obj3.SecureFramesExecuteTransition, d.transition_id);
}
} else if (obj.DAVE_PROTOCOL_PREPARE_EPOCH === op) {
const tmp25 = null != d.epoch && null != d.protocol_version;
if (tmp25) {
obj.emit(obj3.SecureFramesPrepareEpoch, d.epoch, d.protocol_version);
}
} else if (obj.MLS_EXTERNAL_SENDER_PACKAGE === op) {
obj.emit(obj3.MLSExternalSenderPackage, d);
} else if (obj.MLS_PROPOSALS === op) {
obj.emit(obj3.MLSProposals, d);
} else if (obj.MLS_PREPARE_COMMIT_TRANSITION === op) {
const _DataView2 = DataView;
const self3 = this;
const self4 = this;
const dataView = new DataView(d.buffer, d.byteOffset, 2);
const uint16 = dataView.getUint16(0, false);
obj.emit(obj3.MLSPrepareCommitTransition, uint16, d.slice(2));
} else if (obj.MLS_WELCOME === op) {
const _DataView = DataView;
self = this;
const self2 = this;
const dataView1 = new DataView(d.buffer, d.byteOffset, 2);
const uint161 = dataView1.getUint16(0, false);
obj.emit(obj3.MLSWelcome, uint161, d.slice(2));
} else {
const logger3 = obj.logger;
const _HermesInternal3 = HermesInternal;
logger3.info("Unhandled op " + op);
}
};
webSocket.onerror = () => self.handleClose(false, 0, "An error with the websocket occurred");
webSocket.onclose = (wasClean) => self.handleClose(wasClean.wasClean, wasClean.code, wasClean.reason);
}
send(op) {
let tmp = arg1;
if (arg1 === undefined) {
tmp = null;
}
const self = this;
const webSocket = this.webSocket;
if (null != webSocket) {
const _WebSocket = WebSocket;
if (webSocket.readyState === WebSocket.OPEN) {
const _JSON = JSON;
const obj = { op, d: tmp };
const json = JSON.stringify(obj);
if (DeveloperOptionsStore.isLoggingGatewayEvents) {
const logger = self.logger;
const _HermesInternal = HermesInternal;
logger.info("<~ " + json);
}
self.emit(obj3.SendMessage, op, tmp);
try {
webSocket.send(json);
} catch (err) {
}
}
}
}
sendBinary(MLS_COMMIT_WELCOME, uint8Array) {
const webSocket = this.webSocket;
if (null != webSocket) {
const _WebSocket = WebSocket;
if (webSocket.readyState === WebSocket.OPEN) {
const _Uint8Array = Uint8Array;
const self = this;
const self2 = this;
uint8Array = new Uint8Array(uint8Array.byteLength + 1);
uint8Array[0] = MLS_COMMIT_WELCOME;
const result = uint8Array.set(uint8Array, 1);
try {
webSocket.send(uint8Array.buffer);
} catch (err) {
}
}
}
}
doResumeOrClose() {
const self = this;
const obj = TimeUtils;
const nowResult = obj.now();
if (null !== this.serverId) {
if (null !== self.channelId) {
if (null !== self.token) {
if (null !== self.sessionId) {
if (self.resumable) {
self.doResume();
self.lastHeartbeatAckTime = nowResult;
}
}
}
}
}
self.disconnect(false, obj2.UNRESUMABLE, "Cannot resume connection.");
}
doResume() {
let logger;
let serverId;
const self = this;
let num = this.lastRecvSeqNum;
if (num == null) {
num = -1;
}
({ logger, serverId } = self);
const info = logger.info;
if (serverId == null) {
serverId = "";
}
let str = self.channelId;
if (str == null) {
str = "";
}
let str2 = self.sessionId;
if (str2 == null) {
str2 = "";
}
info("[RESUME] resuming session. serverId=" + serverId + " channelId=" + str + " sessionId=" + str2 + " seqAck=" + num);
self.emit(obj3.Resuming);
self.connectionState = constants3.RESUMING;
const obj = { token: self.token, session_id: self.sessionId, server_id: self.serverId, channel_id: self.channelId, seq_ack: num };
self.send(obj.RESUME, obj);
}
handleHello(d) {
let heartbeatInterval;
let logger;
let tmp4;
let num = d.v;
if (num == null) {
num = 3;
}
const self = this;
this.serverVersion = num;
if (this.serverVersion <= 3) {
let num3 = 0.1;
const tmp7 = require;
if (PlatformUtils.isPlatformEmbedded) {
num3 = 0.25;
}
self.heartbeatInterval = d.heartbeat_interval * num3;
tmp4 = tmp7;
} else {
self.heartbeatInterval = d.heartbeat_interval * self.heartbeatIntervalModifier;
tmp4 = require;
const tmp = require;
if (!PlatformUtils.isPlatformEmbedded) {
let num2 = self.heartbeatInterval;
const _Math = Math;
const tmp6 = closure_15;
if (num2 == null) {
num2 = NaN;
}
self.heartbeatInterval = min(tmp6, num2);
tmp4 = tmp;
}
}
const tmp4Result = tmp4(4866);
const diff = tmp4Result.now() - self.connectionStartTime;
({ logger, heartbeatInterval } = self);
const info = logger.info;
if (heartbeatInterval == null) {
heartbeatInterval = "??";
}
info("[HELLO] heartbeat interval: " + heartbeatInterval + ", version: " + self.serverVersion + ", took " + diff + " ms");
self.startHeartbeater();
}
handleReady(experiments) {
let ip;
let modes;
let port;
let ssrc;
let streams;
const self = this;
const backoff = this.backoff;
backoff.succeed();
const obj = TimeUtils;
const logger = this.logger;
logger.info("[READY] took " + obj.now() - this.connectionStartTime + " ms");
if (this.serverVersion >= 6) {
self.send(obj.VOICE_BACKEND_VERSION, {});
}
const Ready = obj3.Ready;
({ ip, port, modes, ssrc, streams } = experiments);
let mapped;
const emit = self.emit;
if (streams != null) {
mapped = streams.map(f84375);
}
if (mapped == null) {
mapped = [];
}
emit(Ready, ip, port, modes, ssrc, mapped, experiments.experiments);
}
supportsSfuUpdate() {
return this.serverVersion >= 10;
}
handleResumed() {
const backoff = this.backoff;
backoff.succeed();
}
handleClose(arg0, arg1, arg2) {
let backoff;
let logger2;
const self = this;
let flag = arg0;
let closure_2 = arg1;
let closure_0 = arg2;
this.connectionState = constants3.DISCONNECTED;
if (!arg0) {
flag = false;
}
self.cleanupWebSocket();
if (arg1 !== obj2.AUTHENTICATION_FAILED) {
if (arg1 !== obj2.SERVER_CRASH) {
if (arg1 !== obj2.SERVER_NOT_FOUND) {
if (arg1 !== obj2.INVALID_SESSION) {
if (self.backoff.fails > 3) {
const logger = self.logger;
logger.warn("[WS CLOSED] Backoff exceed. Resetting.");
self.disconnect(flag, arg1, arg2);
} else {
({ backoff, logger: logger2 } = self);
const warn = logger2.warn;
const failResult = backoff.fail(() => self.reconnect(flag, closure_2, closure_0));
const result = failResult / 1000;
const _HermesInternal = HermesInternal;
const str1 = flag.toString();
warn("[WS CLOSED] (clean: " + str1 + ", code: " + arg1 + ", reason: " + arg2 + ") retrying in " + result.toFixed(2) + " seconds.");
}
}
}
}
}
return self.disconnect(flag, arg1, arg2);
}
disconnect(arg0, arg1, arg2) {
const logger = this.logger;
logger.warn("[DISCONNECT] (" + arg0.toString() + ", " + arg1 + ", " + arg2 + ")");
this.cleanupWebSocket();
this.cleanupState();
this.connectionState = constants3.DISCONNECTED;
this.emit(obj3.Disconnect, arg0, arg1, arg2);
}
reconnect(arg0, arg1, arg2) {
const logger = this.logger;
logger.info("[RECONNECT] wasClean=" + arg0.toString() + " code=" + arg1 + " reason=" + arg2);
this.cleanupWebSocket((close) => close.close(4000));
this.connectionState = constants3.RECONNECTING;
const webSocket = this.createWebSocket();
}
cleanupWebSocket(fn) {
this.stopHeartbeater();
this.clearHelloTimeout();
const webSocket = this.webSocket;
this.webSocket = null;
if (null != webSocket) {
webSocket.onopen = noop;
webSocket.onmessage = noop;
webSocket.onerror = noop;
webSocket.onclose = noop;
if (fn != null) {
fn(webSocket);
}
}
const backoff = this.backoff;
backoff.cancel();
}
cleanupState() {
this.serverId = null;
this.channelId = null;
this.sessionId = null;
this.token = null;
this.resumable = false;
this.lastRecvSeqNum = null;
}
parseWebSocketMessage(data) {
if (data.data instanceof ArrayBuffer) {
const _Uint8Array = Uint8Array;
const self2 = this;
const self3 = this;
const self = this;
const uint8Array = new Uint8Array(data.data);
let uint16 = null;
if (this.serverVersion >= 8) {
const _DataView = DataView;
const self4 = this;
const self5 = this;
const dataView = new DataView(uint8Array.buffer);
uint16 = dataView.getUint16(0, false);
}
let num3 = 0;
if (self.serverVersion >= 8) {
num3 = 2;
}
const obj = { op: uint8Array[num3], seq: uint16, d: uint8Array.subarray(num3 + 1) };
return obj;
} else {
const _JSON = JSON;
return JSON.parse(data.data);
}
}
clearHelloTimeout() {
const self = this;
if (null != this.helloTimeout) {
const _clearTimeout = clearTimeout;
clearTimeout(self.helloTimeout);
self.helloTimeout = null;
}
}
handleHeartbeatAck(d) {
const self = this;
const logger = this.logger;
logger.info("Heartbeat ACK received");
let t = d;
if (this.serverVersion >= 8) {
t = d.t;
}
const emit = self.emit;
const Ping = obj3.Ping;
const obj = TimeUtils;
emit(Ping, obj.now() - t);
obj2 = TimeUtils;
self.lastHeartbeatAckTime = obj2.now();
self.heartbeatAck = true;
if (null !== self.expeditedHeartbeatTimeout) {
const _clearTimeout = clearTimeout;
clearTimeout(self.expeditedHeartbeatTimeout);
self.expeditedHeartbeatTimeout = null;
const logger2 = self.logger;
logger2.info("Expedited heartbeat succeeded");
}
}
handleHeartbeatTimeout() {
let backoff;
let logger;
const self = this;
this.cleanupWebSocket((close) => close.close(4000));
({ backoff, logger } = this);
const result = backoff.fail(() => self.reconnect(false, obj2.HEARTBEAT_TIMEOUT, "Heartbeat timeout.")) / 1000;
logger.warn("[HEARTBEAT ACK TIMEOUT] reconnecting in " + result.toFixed(2) + " seconds.");
}
startHeartbeater() {
const self = this;
_modDef38(null != this.heartbeatInterval, "RTCControlSocket: Heartbeat interval should never null here.");
const logger = this.logger;
logger.info("Starting heartbeat with interval: " + this.heartbeatInterval);
if (null !== this.heartbeater) {
const _clearInterval = clearInterval;
clearInterval(self.heartbeater);
}
self.heartbeatAck = true;
self.heartbeater = setInterval(() => {
if (self.heartbeatAck) {
self.heartbeatAck = false;
self.sendHeartbeat();
} else if (null === self.expeditedHeartbeatTimeout) {
const result = obj.handleHeartbeatTimeout();
}
}, self.heartbeatInterval);
}
sendHeartbeat() {
let obj;
const self = this;
if (this.serverVersion >= 8) {
let num = self.lastRecvSeqNum;
if (num == null) {
num = -1;
}
const logger2 = self.logger;
const _HermesInternal = HermesInternal;
logger2.info("Sending heartbeat with last received sequence number: " + num);
const send2 = self.send;
const HEARTBEAT2 = obj.HEARTBEAT;
obj2 = { t: obj3.now(), seq_ack: num };
obj3 = TimeUtils;
send2(HEARTBEAT2, obj2);
} else {
const logger = self.logger;
logger.info("Sending heartbeat");
const send = self.send;
const HEARTBEAT = obj.HEARTBEAT;
obj = TimeUtils;
send(HEARTBEAT, obj.now());
}
}
stopHeartbeater() {
const self = this;
if (null !== this.heartbeater) {
const _clearInterval = clearInterval;
clearInterval(self.heartbeater);
self.heartbeater = null;
}
if (null !== self.expeditedHeartbeatTimeout) {
const _clearTimeout = clearTimeout;
clearTimeout(self.expeditedHeartbeatTimeout);
self.expeditedHeartbeatTimeout = null;
}
}
connect() {
let flag;
const self = this;
if (this.connectionState !== constants3.DISCONNECTED) {
const logger = self.logger;
logger.error("Cannot start a new connection, connection state is not disconnected");
flag = false;
} else {
self.connectionState = tmp.CONNECTING;
const webSocket = self.createWebSocket();
self.emit(obj3.Connecting);
flag = true;
}
return flag;
}
identify(streamParameters) {
let channelId;
let mapped;
let maxDaveProtocolVersion;
let serverId;
let sessionId;
let token;
let userId;
let video;
({ serverId, channelId, sessionId, token, video } = streamParameters);
({ userId, maxDaveProtocolVersion } = streamParameters);
if (video === undefined) {
video = false;
}
streamParameters = streamParameters.streamParameters;
this.serverId = serverId;
this.channelId = channelId;
this.sessionId = sessionId;
this.token = token;
this.connectionState = constants3.IDENTIFYING;
const obj = { server_id: serverId, channel_id: channelId, user_id: userId, session_id: sessionId, token, max_dave_protocol_version: maxDaveProtocolVersion, video, streams: mapped };
mapped = undefined;
const send = this.send;
const IDENTIFY = obj.IDENTIFY;
if (streamParameters != null) {
mapped = streamParameters.map(f84374);
}
send(IDENTIFY, obj);
}
expeditedHeartbeat(arg0) {
const self = this;
let str = arg1;
if (arg1 === undefined) {
str = "";
}
let flag = arg2;
if (arg2 === undefined) {
flag = true;
}
if (null != self.webSocket) {
const logger2 = self.logger;
let str5 = "";
const info2 = logger2.info;
if ("" !== str) {
str5 = `reason: ${str}`;
}
info2(`Performing an expedited heartbeat ${str5}`);
self.heartbeatAck = false;
self.sendHeartbeat();
if (null !== self.expeditedHeartbeatTimeout) {
const _clearTimeout = clearTimeout;
clearTimeout(self.expeditedHeartbeatTimeout);
}
const _setTimeout = setTimeout;
self.expeditedHeartbeatTimeout = setTimeout(() => {
self.expeditedHeartbeatTimeout = null;
const obj = self;
if (false === self.heartbeatAck) {
const result = obj.handleHeartbeatTimeout();
}
}, arg0);
} else if (flag) {
return self.resetBackoff(str);
} else {
const logger = self.logger;
let str2 = "";
const info = logger.info;
if ("" !== str) {
str2 = `reason: ${str}`;
}
info(`Expedited heartbeat requested, but is disconnected and a reset was not requested ${str2}`);
}
return false;
}
resetBackoff() {
let str = arg0;
if (arg0 === undefined) {
str = "";
}
const self = this;
let flag = this.backoff.fails > 0 && null == self.webSocket;
if (flag) {
const logger = self.logger;
let str2 = "";
const info = logger.info;
if ("" !== str) {
str2 = `for reason: ${str}`;
}
info(`Connection backoff reset ${str2}`);
const backoff = self.backoff;
backoff.succeed();
self.reconnect(false, obj2.RESET_BACKOFF, "Reset backoff.");
flag = true;
}
return flag;
}
close() {
const logger = this.logger;
logger.info("CLOSE");
this.cleanupWebSocket((close) => close.close(4000));
this.cleanupState();
this.connectionState = constants3.DISCONNECTED;
this.emit(obj3.Disconnect, true, 1000, "Force Close");
}
destroy() {
this.close();
}
selectProtocol(protocol, rTCConnectionId, sdp, _selectedExperiments) {
let codecs;
let codecs1;
const obj = {};
let tmp = obj;
sdp = null;
if (null != sdp) {
if ("sdp" in sdp) {
if (null != sdp.sdp) {
if ("" !== sdp.sdp) {
sdp = sdp.sdp;
obj3 = { codecs: codecs.map(f84373), rtc_connection_id: rTCConnectionId };
const merged = Object.assign(sdp);
codecs = sdp.codecs;
tmp = obj3;
}
}
}
let BooleanResult = "address" in sdp && null != sdp.address && "" !== sdp.address;
if (BooleanResult) {
const _Boolean = Boolean;
BooleanResult = Boolean(sdp.port);
}
if (BooleanResult) {
BooleanResult = null != sdp.mode;
}
if (BooleanResult) {
BooleanResult = "" !== sdp.mode;
}
tmp = obj;
if (BooleanResult) {
const obj4 = { address: null, port: null, mode: null };
({ address: obj2.address, port: obj2.port, mode: obj2.mode } = sdp);
const obj5 = { codecs: codecs1.map(f84373), rtc_connection_id: rTCConnectionId, experiments: _selectedExperiments };
const merged1 = Object.assign(sdp);
codecs1 = sdp.codecs;
tmp = obj5;
sdp = obj4;
}
}
const send = this.send;
const SELECT_PROTOCOL = obj.SELECT_PROTOCOL;
const obj9 = { protocol, data: sdp };
const merged2 = Object.assign(tmp);
send(SELECT_PROTOCOL, obj9);
}
updateSession(codecs) {
const obj = { codecs: codecs.map(f84373) };
codecs = codecs.codecs;
const send = this.send;
const SESSION_UPDATE = obj.SESSION_UPDATE;
send(SESSION_UPDATE, obj);
}
speaking(_lastSentSpeakingStatus, packetDelay, _lastSentSSRC) {
let num = packetDelay;
if (packetDelay === undefined) {
num = 0;
}
let num2 = _lastSentSSRC;
if (_lastSentSSRC === undefined) {
num2 = 0;
}
let BooleanResult = _lastSentSpeakingStatus;
const send = this.send;
const SPEAKING = obj.SPEAKING;
if (this.serverVersion <= 3) {
const _Boolean = Boolean;
BooleanResult = Boolean(_lastSentSpeakingStatus);
}
send(SPEAKING, { speaking: BooleanResult, delay: num, ssrc: num2 });
}
video(audio_ssrc, video_ssrc, rtx_ssrc, arr) {
let mapped;
let obj = { audio_ssrc, video_ssrc, rtx_ssrc, streams: mapped };
mapped = undefined;
const send = this.send;
const VIDEO = obj.VIDEO;
if (arr != null) {
mapped = arr.map(f84374);
}
send(VIDEO, obj);
}
mediaSinkWants(localVideoSinkWants) {
const self = this;
if (this.serverVersion >= 5) {
self.send(obj.MEDIA_SINK_WANTS, localVideoSinkWants);
}
}
secureFramesReadyForTransition(transition_id) {
const obj = { transition_id };
this.send(obj.DAVE_PROTOCOL_READY_FOR_TRANSITION, obj);
}
sendMLSKeyPackage(arg0) {
const logger = this.logger;
logger.info("Sending MLS key package");
const sendBinary = this.sendBinary;
const MLS_KEY_PACKAGE = obj.MLS_KEY_PACKAGE;
const uint8Array = new Uint8Array(arg0);
sendBinary(MLS_KEY_PACKAGE, uint8Array);
}
sendMLSCommitWelcome(byteLength) {
const logger = this.logger;
logger.info("Sending MLS commit + welcome message");
const sendBinary = this.sendBinary;
const MLS_COMMIT_WELCOME = obj.MLS_COMMIT_WELCOME;
const uint8Array = new Uint8Array(byteLength);
sendBinary(MLS_COMMIT_WELCOME, uint8Array);
}
flagMLSInvalidCommitWelcome(transition_id) {
const obj = { transition_id };
this.send(obj.MLS_INVALID_COMMIT_WELCOME, obj);
}
disconnectForRepeatedMLSInvalidMessages(arg0) {
const logger = this.logger;
logger.warn("[MLS] " + arg0 + " consecutive invalid commit/welcome messages.");
this.cleanupWebSocket((close) => close.close(constants.REPEATED_MLS_INVALID_MESSAGES));
this.disconnect(false, obj2.REPEATED_MLS_INVALID_MESSAGES, "Repeated invalid MLS commit/welcome messages.");
}
disconnectForRefusedDaveDowngrade(EPOCH) {
const logger = this.logger;
logger.warn("[DAVE] Refused protocol downgrade to version 0 at " + EPOCH + ".");
this.cleanupWebSocket((close) => close.close(constants.DAVE_DOWNGRADE_REFUSED));
this.disconnect(false, obj2.DAVE_DOWNGRADE_REFUSED, "Refused DAVE protocol downgrade.");
}
noRoute() {
this.send(obj.CLIENT_CANNOT_REACH_RTC_SERVER, {});
}
setHeartbeatIntervalModifier(heartbeatIntervalModifier) {
this.heartbeatIntervalModifier = heartbeatIntervalModifier;
}
}
const prototype = RTCControlSocket.prototype;
let size = size_mod;
let result = size.fileFinishedImporting("lib/RTCControlSocket.tsx");
export default RTCControlSocket;
export { RTCSocketOpcode };
export const RTCSocketCloseCode = obj2;
export const SocketEvent = obj3;