fcr-core 3.8.1 → 3.9.0-alpha
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/lib/chat-connector/type.d.ts +40 -0
- package/lib/{chat-connection → chat-connector}/type.js +1 -1
- package/lib/engine/index.d.ts +10 -11
- package/lib/engine/index.js +63 -72
- package/lib/engine/type.d.ts +96 -0
- package/lib/engine/type.js +5 -0
- package/lib/imports.d.ts +7 -4
- package/lib/imports.js +30 -4
- package/lib/index.d.ts +3 -2
- package/lib/index.js +21 -2
- package/lib/media-control/desktop.js +12 -12
- package/lib/media-control/mobile.js +4 -0
- package/lib/media-control/type.d.ts +32 -33
- package/lib/monitor-control/index.js +3 -3
- package/lib/peer-session/index.js +14 -14
- package/lib/peer-session/type.d.ts +1 -1
- package/lib/plugins/chat/chatroom.js +417 -0
- package/lib/{chat-connection → plugins/chat}/config.d.ts +1 -0
- package/lib/{room-control/chatroom-control → plugins/chat}/config.js +2 -1
- package/lib/plugins/chat/connector.d.ts +38 -0
- package/lib/{chat-connection/index.js → plugins/chat/connector.js} +181 -61
- package/lib/room-control/ability-control/index.js +5 -4
- package/lib/room-control/ability-control/type.d.ts +5 -1
- package/lib/room-control/ability-control/type.js +4 -0
- package/lib/room-control/chatroom-control/type.d.ts +44 -35
- package/lib/room-control/group-control/index.js +9 -9
- package/lib/room-control/index.js +37 -22
- package/lib/room-control/interpreter-control/index.js +7 -4
- package/lib/room-control/interpreter-control/room.js +3 -3
- package/lib/room-control/interpreter-control/types.d.ts +2 -2
- package/lib/room-control/join-before-host-waitingroom-control/index.js +3 -3
- package/lib/room-control/mainroom-control/index.js +15 -13
- package/lib/room-control/privilege-control/index.js +39 -24
- package/lib/room-control/privilege-control/type.d.ts +15 -15
- package/lib/room-control/room-connector-control/index.js +7 -5
- package/lib/room-control/room-connector-control/type.d.ts +1 -1
- package/lib/room-control/room-control-factory.d.ts +3 -3
- package/lib/room-control/room-control-factory.js +7 -7
- package/lib/room-control/room-session/index.js +17 -15
- package/lib/room-control/room-session/type.d.ts +3 -3
- package/lib/room-control/sharing-control/index.js +13 -7
- package/lib/room-control/stream-control/index.js +18 -16
- package/lib/room-control/stream-control/type.d.ts +5 -5
- package/lib/room-control/stt-control/index.js +38 -31
- package/lib/room-control/type.d.ts +19 -19
- package/lib/room-control/user-control/index.js +20 -22
- package/lib/room-control/user-control/type.d.ts +1 -1
- package/lib/room-control/waitingroom-control/index.js +11 -11
- package/lib/room-control/whiteboard-control-v1/board-window.d.ts +21 -20
- package/lib/room-control/whiteboard-control-v1/board-window.js +27 -8
- package/lib/room-control/whiteboard-control-v1/factory.js +1 -1
- package/lib/room-control/whiteboard-control-v1/index.js +26 -18
- package/lib/room-control/whiteboard-control-v1/type.d.ts +26 -25
- package/lib/room-control/whiteboard-control-v1/type.js +1 -0
- package/lib/room-control/whiteboard-control-v2/annotation-control/control.d.ts +15 -6
- package/lib/room-control/whiteboard-control-v2/annotation-control/control.js +39 -5
- package/lib/room-control/whiteboard-control-v2/annotation-control/factory.d.ts +4 -5
- package/lib/room-control/whiteboard-control-v2/annotation-control/factory.js +6 -5
- package/lib/room-control/whiteboard-control-v2/annotation-control/type.d.ts +7 -1
- package/lib/room-control/whiteboard-control-v2/base/index.d.ts +9 -8
- package/lib/room-control/whiteboard-control-v2/base/index.js +84 -42
- package/lib/room-control/whiteboard-control-v2/base/main-window.d.ts +16 -15
- package/lib/room-control/whiteboard-control-v2/base/main-window.js +23 -4
- package/lib/room-control/whiteboard-control-v2/type.d.ts +17 -17
- package/lib/room-control/whiteboard-control-v2/whiteboard-control/control.d.ts +12 -6
- package/lib/room-control/whiteboard-control-v2/whiteboard-control/control.js +64 -18
- package/lib/room-control/whiteboard-control-v2/whiteboard-control/factory.d.ts +2 -2
- package/lib/room-control/whiteboard-control-v2/whiteboard-control/factory.js +10 -10
- package/lib/room-control/whiteboard-control-v2/whiteboard-control/type.d.ts +1 -1
- package/lib/room-router/index.js +10 -7
- package/lib/room-router/type.d.ts +1 -1
- package/lib/schema.d.ts +24 -46
- package/lib/schema.js +1 -2
- package/lib/service/api.d.ts +5 -3
- package/lib/service/api.js +17 -12
- package/lib/type.d.ts +64 -45
- package/lib/type.js +76 -11
- package/lib/utilities/abortable-retry.d.ts +38 -0
- package/lib/utilities/abortable-retry.js +61 -0
- package/lib/utilities/dual-video-stream-config.d.ts +6 -0
- package/lib/utilities/dual-video-stream-config.js +25 -0
- package/lib/utilities/error-helpers.d.ts +10 -9
- package/lib/utilities/error-helpers.js +12 -11
- package/lib/utilities/error.d.ts +4 -40
- package/lib/utilities/error.js +20 -77
- package/lib/utilities/join-helper.js +2 -2
- package/lib/utilities/logger.d.ts +2 -2
- package/lib/utilities/logger.js +6 -25
- package/lib/utilities/package-info.d.ts +1 -2
- package/lib/utilities/package-info.js +4 -8
- package/lib/utilities/parameters.js +88 -15
- package/lib/utilities/validate-params.js +1 -1
- package/lib/utilities/video-encoder-config.d.ts +9 -0
- package/lib/utilities/video-encoder-config.js +109 -0
- package/lib-es/base-session.js +1 -0
- package/lib-es/chat-connector/type.js +6 -0
- package/lib-es/engine/index.js +412 -0
- package/lib-es/engine/type.js +1 -0
- package/lib-es/imports.js +59 -0
- package/lib-es/index.js +8 -0
- package/lib-es/media-control/desktop.js +172 -0
- package/lib-es/media-control/mobile.js +198 -0
- package/lib-es/media-control/type.js +6 -0
- package/lib-es/monitor-control/index.js +46 -0
- package/lib-es/monitor-control/type.js +1 -0
- package/lib-es/peer-session/index.js +279 -0
- package/lib-es/peer-session/type.js +1 -0
- package/lib-es/plugins/chat/chatroom.js +409 -0
- package/{lib/chat-connection → lib-es/plugins/chat}/config.js +5 -9
- package/lib-es/plugins/chat/connector.js +269 -0
- package/lib-es/plugins/electron-rtc-plugin.js +1 -0
- package/lib-es/plugins/rtm-plugin.js +1 -0
- package/lib-es/plugins/web-rtc-plugin.js +1 -0
- package/lib-es/room-control/ability-control/index.js +58 -0
- package/lib-es/room-control/ability-control/type.js +15 -0
- package/lib-es/room-control/chatroom-control/type.js +12 -0
- package/lib-es/room-control/group-control/index.js +256 -0
- package/lib-es/room-control/helpers/constants.js +92 -0
- package/lib-es/room-control/helpers/index.js +20 -0
- package/lib-es/room-control/helpers/validation-helper.js +46 -0
- package/lib-es/room-control/index.js +623 -0
- package/lib-es/room-control/interpreter-control/index.js +172 -0
- package/lib-es/room-control/interpreter-control/room.js +28 -0
- package/lib-es/room-control/interpreter-control/types.js +26 -0
- package/lib-es/room-control/join-before-host-waitingroom-control/index.js +29 -0
- package/lib-es/room-control/mainroom-control/index.js +248 -0
- package/lib-es/room-control/privilege-control/helper.js +97 -0
- package/lib-es/room-control/privilege-control/index.js +339 -0
- package/lib-es/room-control/privilege-control/type.js +159 -0
- package/lib-es/room-control/room-connector-control/index.js +182 -0
- package/lib-es/room-control/room-connector-control/type.js +28 -0
- package/lib-es/room-control/room-control-factory.js +77 -0
- package/lib-es/room-control/room-session/index.js +292 -0
- package/lib-es/room-control/room-session/type.js +1 -0
- package/lib-es/room-control/shared-cache.js +47 -0
- package/lib-es/room-control/sharing-control/index.js +307 -0
- package/lib-es/room-control/sharing-control/type.js +16 -0
- package/lib-es/room-control/stream-control/index.js +536 -0
- package/lib-es/room-control/stream-control/type.js +1 -0
- package/lib-es/room-control/stt-control/de-compress-gzip.js +33 -0
- package/lib-es/room-control/stt-control/index.js +350 -0
- package/lib-es/room-control/stt-control/type.js +10 -0
- package/lib-es/room-control/type.js +30 -0
- package/lib-es/room-control/user-control/index.js +344 -0
- package/lib-es/room-control/user-control/type.js +21 -0
- package/lib-es/room-control/waitingroom-control/index.js +68 -0
- package/lib-es/room-control/whiteboard-control/enum.js +18 -0
- package/lib-es/room-control/whiteboard-control/type.js +10 -0
- package/lib-es/room-control/whiteboard-control/utils.js +13 -0
- package/lib-es/room-control/whiteboard-control-v1/board-subwindow.js +18 -0
- package/lib-es/room-control/whiteboard-control-v1/board-window.js +573 -0
- package/lib-es/room-control/whiteboard-control-v1/enum.js +157 -0
- package/lib-es/room-control/whiteboard-control-v1/factory.js +12 -0
- package/lib-es/room-control/whiteboard-control-v1/index.js +427 -0
- package/lib-es/room-control/whiteboard-control-v1/mount-manager.js +6 -0
- package/lib-es/room-control/whiteboard-control-v1/type.js +8 -0
- package/lib-es/room-control/whiteboard-control-v1/utils.js +273 -0
- package/lib-es/room-control/whiteboard-control-v2/annotation-control/control.js +76 -0
- package/lib-es/room-control/whiteboard-control-v2/annotation-control/factory.js +37 -0
- package/lib-es/room-control/whiteboard-control-v2/annotation-control/type.js +1 -0
- package/lib-es/room-control/whiteboard-control-v2/base/index.js +347 -0
- package/lib-es/room-control/whiteboard-control-v2/base/main-window.js +269 -0
- package/lib-es/room-control/whiteboard-control-v2/constant.js +9 -0
- package/lib-es/room-control/whiteboard-control-v2/enum.js +28 -0
- package/lib-es/room-control/whiteboard-control-v2/type.js +1 -0
- package/lib-es/room-control/whiteboard-control-v2/utils.js +92 -0
- package/lib-es/room-control/whiteboard-control-v2/whiteboard-control/control.js +204 -0
- package/lib-es/room-control/whiteboard-control-v2/whiteboard-control/factory.js +61 -0
- package/lib-es/room-control/whiteboard-control-v2/whiteboard-control/type.js +1 -0
- package/lib-es/room-router/index.js +263 -0
- package/lib-es/room-router/type.js +5 -0
- package/lib-es/schema.js +231 -0
- package/lib-es/service/api.js +1211 -0
- package/lib-es/service/type.js +1 -0
- package/lib-es/type.js +222 -0
- package/lib-es/utilities/abortable-retry.js +54 -0
- package/lib-es/utilities/cmd.js +1 -0
- package/lib-es/utilities/collection.js +64 -0
- package/lib-es/utilities/dual-video-stream-config.js +19 -0
- package/lib-es/utilities/error-helpers.js +224 -0
- package/lib-es/utilities/error.js +43 -0
- package/lib-es/utilities/join-helper.js +219 -0
- package/lib-es/utilities/logger.js +7 -0
- package/lib-es/utilities/package-info.js +5 -0
- package/lib-es/utilities/parameters.js +106 -0
- package/lib-es/utilities/retry-helpers.js +66 -0
- package/lib-es/utilities/shared-storage.js +31 -0
- package/lib-es/utilities/stream.js +18 -0
- package/lib-es/utilities/user.js +30 -0
- package/lib-es/utilities/validate-params.js +8 -0
- package/lib-es/utilities/video-encoder-config.js +103 -0
- package/package.json +11 -10
- package/lib/chat-connection/index.d.ts +0 -24
- package/lib/chat-connection/type.d.ts +0 -17
- package/lib/plugins/chatroom.js +0 -454
- package/lib/room-control/chatroom-control/config.d.ts +0 -51
- package/lib/utilities/storage.d.ts +0 -8
- package/lib/utilities/storage.js +0 -33
- /package/lib/plugins/{chatroom.d.ts → chat/chatroom.d.ts} +0 -0
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import "core-js/modules/esnext.function.metadata.js";
|
|
2
|
+
import "core-js/modules/esnext.map.delete-all.js";
|
|
3
|
+
import "core-js/modules/esnext.map.emplace.js";
|
|
4
|
+
import "core-js/modules/esnext.map.every.js";
|
|
5
|
+
import "core-js/modules/esnext.map.filter.js";
|
|
6
|
+
import "core-js/modules/esnext.map.find.js";
|
|
7
|
+
import "core-js/modules/esnext.map.find-key.js";
|
|
8
|
+
import "core-js/modules/esnext.map.includes.js";
|
|
9
|
+
import "core-js/modules/esnext.map.key-of.js";
|
|
10
|
+
import "core-js/modules/esnext.map.map-keys.js";
|
|
11
|
+
import "core-js/modules/esnext.map.map-values.js";
|
|
12
|
+
import "core-js/modules/esnext.map.merge.js";
|
|
13
|
+
import "core-js/modules/esnext.map.reduce.js";
|
|
14
|
+
import "core-js/modules/esnext.map.some.js";
|
|
15
|
+
import "core-js/modules/esnext.map.update.js";
|
|
16
|
+
import "core-js/modules/esnext.symbol.metadata.js";
|
|
17
|
+
let _initProto, _startSessionByPhoneDecs, _startSessionByIPDecs, _stopSessionDecs;
|
|
18
|
+
import "core-js/modules/es.array.push.js";
|
|
19
|
+
import "core-js/modules/esnext.iterator.constructor.js";
|
|
20
|
+
import "core-js/modules/esnext.iterator.map.js";
|
|
21
|
+
import "core-js/modules/esnext.iterator.reduce.js";
|
|
22
|
+
function _applyDecs(e, t, r, n, o, a) { function i(e, t, r) { return function (n, o) { return r && r(n), e[t].call(n, o); }; } function c(e, t) { for (var r = 0; r < e.length; r++) e[r].call(t); return t; } function s(e, t, r, n) { if ("function" != typeof e && (n || void 0 !== e)) throw new TypeError(t + " must " + (r || "be") + " a function" + (n ? "" : " or undefined")); return e; } function applyDec(e, t, r, n, o, a, c, u, l, f, p, d, h) { function m(e) { if (!h(e)) throw new TypeError("Attempted to access private element on non-instance"); } var y, v = t[0], g = t[3], b = !u; if (!b) { r || Array.isArray(v) || (v = [v]); var w = {}, S = [], A = 3 === o ? "get" : 4 === o || d ? "set" : "value"; f ? (p || d ? w = { get: _setFunctionName(function () { return g(this); }, n, "get"), set: function (e) { t[4](this, e); } } : w[A] = g, p || _setFunctionName(w[A], n, 2 === o ? "" : A)) : p || (w = Object.getOwnPropertyDescriptor(e, n)); } for (var P = e, j = v.length - 1; j >= 0; j -= r ? 2 : 1) { var D = v[j], E = r ? v[j - 1] : void 0, I = {}, O = { kind: ["field", "accessor", "method", "getter", "setter", "class"][o], name: n, metadata: a, addInitializer: function (e, t) { if (e.v) throw Error("attempted to call addInitializer after decoration was finished"); s(t, "An initializer", "be", !0), c.push(t); }.bind(null, I) }; try { if (b) (y = s(D.call(E, P, O), "class decorators", "return")) && (P = y);else { var k, F; O.static = l, O.private = f, f ? 2 === o ? k = function (e) { return m(e), w.value; } : (o < 4 && (k = i(w, "get", m)), 3 !== o && (F = i(w, "set", m))) : (k = function (e) { return e[n]; }, (o < 2 || 4 === o) && (F = function (e, t) { e[n] = t; })); var N = O.access = { has: f ? h.bind() : function (e) { return n in e; } }; if (k && (N.get = k), F && (N.set = F), P = D.call(E, d ? { get: w.get, set: w.set } : w[A], O), d) { if ("object" == typeof P && P) (y = s(P.get, "accessor.get")) && (w.get = y), (y = s(P.set, "accessor.set")) && (w.set = y), (y = s(P.init, "accessor.init")) && S.push(y);else if (void 0 !== P) throw new TypeError("accessor decorators must return an object with get, set, or init properties or void 0"); } else s(P, (p ? "field" : "method") + " decorators", "return") && (p ? S.push(P) : w[A] = P); } } finally { I.v = !0; } } return (p || d) && u.push(function (e, t) { for (var r = S.length - 1; r >= 0; r--) t = S[r].call(e, t); return t; }), p || b || (f ? d ? u.push(i(w, "get"), i(w, "set")) : u.push(2 === o ? w[A] : i.call.bind(w[A])) : Object.defineProperty(e, n, w)), P; } function u(e, t) { return Object.defineProperty(e, Symbol.metadata || Symbol.for("Symbol.metadata"), { configurable: !0, enumerable: !0, value: t }); } if (arguments.length >= 6) var l = a[Symbol.metadata || Symbol.for("Symbol.metadata")]; var f = Object.create(null == l ? null : l), p = function (e, t, r, n) { var o, a, i = [], s = function (t) { return _checkInRHS(t) === e; }, u = new Map(); function l(e) { e && i.push(c.bind(null, e)); } for (var f = 0; f < t.length; f++) { var p = t[f]; if (Array.isArray(p)) { var d = p[1], h = p[2], m = p.length > 3, y = 16 & d, v = !!(8 & d), g = 0 == (d &= 7), b = h + "/" + v; if (!g && !m) { var w = u.get(b); if (!0 === w || 3 === w && 4 !== d || 4 === w && 3 !== d) throw Error("Attempted to decorate a public method/accessor that has the same name as a previously decorated public method/accessor. This is not currently supported by the decorators plugin. Property name was: " + h); u.set(b, !(d > 2) || d); } applyDec(v ? e : e.prototype, p, y, m ? "#" + h : _toPropertyKey(h), d, n, v ? a = a || [] : o = o || [], i, v, m, g, 1 === d, v && m ? s : r); } } return l(o), l(a), i; }(e, t, o, f); return r.length || u(e, f), { e: p, get c() { var t = []; return r.length && [u(applyDec(e, [r], n, e.name, 5, f, t), f), c.bind(null, t, e)]; } }; }
|
|
23
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
24
|
+
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
25
|
+
function _setFunctionName(e, t, n) { "symbol" == typeof t && (t = (t = t.description) ? "[" + t + "]" : ""); try { Object.defineProperty(e, "name", { configurable: !0, value: n ? n + " " + t : t }); } catch (e) {} return e; }
|
|
26
|
+
function _checkInRHS(e) { if (Object(e) !== e) throw TypeError("right-hand side of 'in' should be an object, got " + (null !== e ? typeof e : "null")); return e; }
|
|
27
|
+
import { FcrIPConnectorSessionType, FcrRoomConnectorPhoneRegion, FcrRoomConnectorSessionReason, FcrRoomConnectorSessionState } from './type';
|
|
28
|
+
import { AgoraObservable, trace } from '../../imports';
|
|
29
|
+
import { createLogger, generateLogObserver } from '../../utilities/logger';
|
|
30
|
+
import { handleRequestError } from '../../utilities/error';
|
|
31
|
+
import validateParams from '../../utilities/validate-params';
|
|
32
|
+
import { fcrIPConnectorSessionParamsSchema, fcrPhoneConnectorSessionParamsSchema, stringSchema } from '../../schema';
|
|
33
|
+
import { FcrReturnCode } from '../../type';
|
|
34
|
+
import { ErrorModuleCode } from '../../imports';
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* @internal
|
|
38
|
+
*/
|
|
39
|
+
export class FcrRoomConnectorControlImpl {
|
|
40
|
+
static {
|
|
41
|
+
[_initProto] = _applyDecs(this, [[trace, 2, "getRoomConnectorPhoneInfo"], [trace, 2, "getRoomConnectorIpInfo"], [_startSessionByPhoneDecs, 2, "startSessionByPhone"], [_startSessionByIPDecs, 2, "startSessionByIP"], [_stopSessionDecs, 2, "stopSession"]], []).e;
|
|
42
|
+
}
|
|
43
|
+
//@internal
|
|
44
|
+
[(_startSessionByPhoneDecs = [trace(['params']), validateParams(fcrPhoneConnectorSessionParamsSchema)], _startSessionByIPDecs = [trace(['params']), validateParams(fcrIPConnectorSessionParamsSchema)], _stopSessionDecs = [trace(['sessionId']), validateParams(stringSchema)], "logger")] = (_initProto(this), createLogger({
|
|
45
|
+
prefix: 'FcrRoomConnectorControlImpl'
|
|
46
|
+
}));
|
|
47
|
+
_observable = new AgoraObservable();
|
|
48
|
+
constructor(_scene, _engine, _api) {
|
|
49
|
+
this._scene = _scene;
|
|
50
|
+
this._engine = _engine;
|
|
51
|
+
this._api = _api;
|
|
52
|
+
this._addLogObserver();
|
|
53
|
+
this._scene.addObserver({
|
|
54
|
+
onSceneMessageReceived: this._handleMessageReceived.bind(this)
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
getRoomConnectorPhoneInfo() {
|
|
58
|
+
const mid = this._scene.getScenePropertiesByKeyPath('call.mid');
|
|
59
|
+
const callIn = this._scene.getScenePropertiesByKeyPath('call.callIn') ?? [];
|
|
60
|
+
const uid = this._scene.getUserPropertiesByKeyPath('call.uid', this._scene.getLocalUser().getLocalUserId());
|
|
61
|
+
const regionMap = {
|
|
62
|
+
cn: FcrRoomConnectorPhoneRegion.CN
|
|
63
|
+
};
|
|
64
|
+
return Promise.resolve(callIn.map(({
|
|
65
|
+
callNumbers,
|
|
66
|
+
region
|
|
67
|
+
}) => {
|
|
68
|
+
return {
|
|
69
|
+
region: regionMap[region],
|
|
70
|
+
phoneNumberList: callNumbers,
|
|
71
|
+
phoneRoomId: mid,
|
|
72
|
+
phoneUserId: uid
|
|
73
|
+
};
|
|
74
|
+
}));
|
|
75
|
+
}
|
|
76
|
+
getRoomConnectorIpInfo() {
|
|
77
|
+
const mid = this._scene.getScenePropertiesByKeyPath('call.mid');
|
|
78
|
+
const callIn = this._scene.getScenePropertiesByKeyPath('call.callIn') ?? [];
|
|
79
|
+
return Promise.resolve({
|
|
80
|
+
addressList: callIn.reduce((prev, {
|
|
81
|
+
ipAddresses
|
|
82
|
+
}) => {
|
|
83
|
+
if (Array.isArray(ipAddresses)) {
|
|
84
|
+
prev.push(...ipAddresses);
|
|
85
|
+
}
|
|
86
|
+
return prev;
|
|
87
|
+
}, []),
|
|
88
|
+
ipRoomId: mid
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
async startSessionByPhone(params) {
|
|
92
|
+
const {
|
|
93
|
+
data
|
|
94
|
+
} = await handleRequestError(() => this._api.callPstn({
|
|
95
|
+
roomId: this._scene.sceneId,
|
|
96
|
+
callNumber: params.phoneNumber,
|
|
97
|
+
userId: params.phoneUserId,
|
|
98
|
+
userName: params.userName
|
|
99
|
+
}), ErrorModuleCode.FCR_ROOM, 'start session by phone failed');
|
|
100
|
+
return data.data.sessionUuid;
|
|
101
|
+
}
|
|
102
|
+
async startSessionByIP(params) {
|
|
103
|
+
const callType = {
|
|
104
|
+
[FcrIPConnectorSessionType.H323]: 'h323',
|
|
105
|
+
[FcrIPConnectorSessionType.SIP]: 'sip'
|
|
106
|
+
}[params.type];
|
|
107
|
+
const {
|
|
108
|
+
data
|
|
109
|
+
} = await handleRequestError(() => this._api.callIp({
|
|
110
|
+
roomId: this._scene.sceneId,
|
|
111
|
+
callType,
|
|
112
|
+
ipAddress: params.address
|
|
113
|
+
}), ErrorModuleCode.FCR_ROOM, 'start session by IP failed');
|
|
114
|
+
return data.data.sessionUuid;
|
|
115
|
+
}
|
|
116
|
+
async stopSession(sessionId) {
|
|
117
|
+
await handleRequestError(() => this._api.hangup({
|
|
118
|
+
roomId: this._scene.sceneId,
|
|
119
|
+
callId: sessionId,
|
|
120
|
+
userId: this._scene.getLocalUser().getLocalUserId()
|
|
121
|
+
}), ErrorModuleCode.FCR_ROOM, 'stop session failed');
|
|
122
|
+
return FcrReturnCode.SUCCESS;
|
|
123
|
+
}
|
|
124
|
+
addObserver(observer) {
|
|
125
|
+
this._observable.addObserver(observer);
|
|
126
|
+
}
|
|
127
|
+
removeObserver(observer) {
|
|
128
|
+
this._observable.removeObserver(observer);
|
|
129
|
+
}
|
|
130
|
+
_handleMessageReceived(sceneId, message) {
|
|
131
|
+
const cmd = message.cmd;
|
|
132
|
+
if (cmd === 2001 || cmd === 2002 || cmd === 2003) {
|
|
133
|
+
const {
|
|
134
|
+
sessionUuid,
|
|
135
|
+
payload: {
|
|
136
|
+
callNumber,
|
|
137
|
+
reason,
|
|
138
|
+
callType,
|
|
139
|
+
ipAddress
|
|
140
|
+
}
|
|
141
|
+
} = message.payload;
|
|
142
|
+
const reasonMap = {
|
|
143
|
+
1: FcrRoomConnectorSessionReason.ACCEPTED,
|
|
144
|
+
2: FcrRoomConnectorSessionReason.CANCELED,
|
|
145
|
+
3: FcrRoomConnectorSessionReason.LINE_BUSY,
|
|
146
|
+
4: FcrRoomConnectorSessionReason.TIMEOUT,
|
|
147
|
+
5: FcrRoomConnectorSessionReason.NUMBER_ERROR,
|
|
148
|
+
6: FcrRoomConnectorSessionReason.UNREGISTER,
|
|
149
|
+
7: FcrRoomConnectorSessionReason.SYSTEM_ERROR,
|
|
150
|
+
8: FcrRoomConnectorSessionReason.UNSUPPORTED
|
|
151
|
+
};
|
|
152
|
+
if (callType === 'pstn') {
|
|
153
|
+
const session = {
|
|
154
|
+
sessionId: sessionUuid,
|
|
155
|
+
phoneNumber: callNumber
|
|
156
|
+
};
|
|
157
|
+
if (cmd === 2001) {
|
|
158
|
+
this._observable.notifyObservers('onPhoneConnectorSessionStateUpdated', session, FcrRoomConnectorSessionState.CALLING, FcrRoomConnectorSessionReason.NONE);
|
|
159
|
+
} else if (cmd === 2002) {
|
|
160
|
+
this._observable.notifyObservers('onPhoneConnectorSessionStateUpdated', session, FcrRoomConnectorSessionState.END, reasonMap[reason]);
|
|
161
|
+
} else if (cmd === 2003) {
|
|
162
|
+
this._observable.notifyObservers('onPhoneConnectorSessionStateUpdated', session, FcrRoomConnectorSessionState.RINGING, FcrRoomConnectorSessionReason.NONE);
|
|
163
|
+
}
|
|
164
|
+
} else if (callType === 'h323' || callType === 'sip') {
|
|
165
|
+
const session = {
|
|
166
|
+
sessionId: sessionUuid,
|
|
167
|
+
address: ipAddress
|
|
168
|
+
};
|
|
169
|
+
if (cmd === 2001) {
|
|
170
|
+
this._observable.notifyObservers('onIPConnectorSessionStateUpdated', session, FcrRoomConnectorSessionState.CALLING, FcrRoomConnectorSessionReason.NONE);
|
|
171
|
+
} else if (cmd === 2002) {
|
|
172
|
+
this._observable.notifyObservers('onIPConnectorSessionStateUpdated', session, FcrRoomConnectorSessionState.END, reasonMap[reason]);
|
|
173
|
+
} else if (cmd === 2003) {
|
|
174
|
+
this._observable.notifyObservers('onIPConnectorSessionStateUpdated', session, FcrRoomConnectorSessionState.RINGING, FcrRoomConnectorSessionReason.NONE);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
_addLogObserver() {
|
|
180
|
+
this.addObserver(generateLogObserver(this.logger, [['onIPConnectorSessionStateUpdated', ['session', 'state', 'reason']], ['onPhoneConnectorSessionStateUpdated', ['session', 'state', 'reason']]]));
|
|
181
|
+
}
|
|
182
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export let FcrIPConnectorSessionType = /*#__PURE__*/function (FcrIPConnectorSessionType) {
|
|
2
|
+
FcrIPConnectorSessionType[FcrIPConnectorSessionType["H323"] = 1] = "H323";
|
|
3
|
+
FcrIPConnectorSessionType[FcrIPConnectorSessionType["SIP"] = 2] = "SIP";
|
|
4
|
+
return FcrIPConnectorSessionType;
|
|
5
|
+
}({});
|
|
6
|
+
export let FcrRoomConnectorSessionReason = /*#__PURE__*/function (FcrRoomConnectorSessionReason) {
|
|
7
|
+
FcrRoomConnectorSessionReason[FcrRoomConnectorSessionReason["NONE"] = 0] = "NONE";
|
|
8
|
+
FcrRoomConnectorSessionReason[FcrRoomConnectorSessionReason["ACCEPTED"] = 1] = "ACCEPTED";
|
|
9
|
+
FcrRoomConnectorSessionReason[FcrRoomConnectorSessionReason["CANCELED"] = 2] = "CANCELED";
|
|
10
|
+
FcrRoomConnectorSessionReason[FcrRoomConnectorSessionReason["REJECT"] = 3] = "REJECT";
|
|
11
|
+
FcrRoomConnectorSessionReason[FcrRoomConnectorSessionReason["LINE_BUSY"] = 4] = "LINE_BUSY";
|
|
12
|
+
FcrRoomConnectorSessionReason[FcrRoomConnectorSessionReason["TIMEOUT"] = 5] = "TIMEOUT";
|
|
13
|
+
FcrRoomConnectorSessionReason[FcrRoomConnectorSessionReason["NUMBER_ERROR"] = 6] = "NUMBER_ERROR";
|
|
14
|
+
FcrRoomConnectorSessionReason[FcrRoomConnectorSessionReason["UNREGISTER"] = 7] = "UNREGISTER";
|
|
15
|
+
FcrRoomConnectorSessionReason[FcrRoomConnectorSessionReason["SYSTEM_ERROR"] = 8] = "SYSTEM_ERROR";
|
|
16
|
+
FcrRoomConnectorSessionReason[FcrRoomConnectorSessionReason["UNSUPPORTED"] = 9] = "UNSUPPORTED";
|
|
17
|
+
return FcrRoomConnectorSessionReason;
|
|
18
|
+
}({});
|
|
19
|
+
export let FcrRoomConnectorSessionState = /*#__PURE__*/function (FcrRoomConnectorSessionState) {
|
|
20
|
+
FcrRoomConnectorSessionState[FcrRoomConnectorSessionState["CALLING"] = 1] = "CALLING";
|
|
21
|
+
FcrRoomConnectorSessionState[FcrRoomConnectorSessionState["RINGING"] = 2] = "RINGING";
|
|
22
|
+
FcrRoomConnectorSessionState[FcrRoomConnectorSessionState["END"] = 3] = "END";
|
|
23
|
+
return FcrRoomConnectorSessionState;
|
|
24
|
+
}({});
|
|
25
|
+
export let FcrRoomConnectorPhoneRegion = /*#__PURE__*/function (FcrRoomConnectorPhoneRegion) {
|
|
26
|
+
FcrRoomConnectorPhoneRegion[FcrRoomConnectorPhoneRegion["CN"] = 1] = "CN";
|
|
27
|
+
return FcrRoomConnectorPhoneRegion;
|
|
28
|
+
}({});
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import "core-js/modules/esnext.iterator.constructor.js";
|
|
2
|
+
import "core-js/modules/esnext.iterator.map.js";
|
|
3
|
+
import { DetailErrorCode, ErrorModuleCode, FcrChatRoomControlImpl } from '../imports';
|
|
4
|
+
import { generateFcrCoreClientError } from '../utilities/error';
|
|
5
|
+
import { FcrInterpreterRoomControlImpl } from './interpreter-control/room';
|
|
6
|
+
import { FcrJoinBeforeHostWaitingRoomControlImpl } from './join-before-host-waitingroom-control';
|
|
7
|
+
import { FcrMainRoomControlImpl } from './mainroom-control';
|
|
8
|
+
import { FcrRoomType } from './type';
|
|
9
|
+
import { FcrWaitingRoomControlImpl } from './waitingroom-control';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* 房间控制的创建参数
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* 支持的房间控制类型映射
|
|
17
|
+
*/
|
|
18
|
+
const ROOM_CONTROL_IMPLEMENTATIONS = {
|
|
19
|
+
[FcrRoomType.Waitingroom]: FcrWaitingRoomControlImpl,
|
|
20
|
+
[FcrRoomType.JoinBeforeHostWaitingRoom]: FcrJoinBeforeHostWaitingRoomControlImpl,
|
|
21
|
+
[FcrRoomType.Mainroom]: FcrMainRoomControlImpl,
|
|
22
|
+
[FcrRoomType.Interpreterroom]: FcrInterpreterRoomControlImpl,
|
|
23
|
+
// 注意:Subroom 目前没有专门的实现类,使用主房间控制
|
|
24
|
+
[FcrRoomType.Subroom]: FcrMainRoomControlImpl
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* 房间控制工厂类
|
|
29
|
+
* 负责根据房间类型创建相应的房间控制实例
|
|
30
|
+
*/
|
|
31
|
+
export class RoomControlFactory {
|
|
32
|
+
/**
|
|
33
|
+
* 创建房间控制实例
|
|
34
|
+
* @param params 创建参数
|
|
35
|
+
* @returns 房间控制实例
|
|
36
|
+
* @throws {FcrError} 当房间类型不支持时抛出错误
|
|
37
|
+
*/
|
|
38
|
+
static create(params) {
|
|
39
|
+
const {
|
|
40
|
+
engine,
|
|
41
|
+
scene,
|
|
42
|
+
apiService,
|
|
43
|
+
config,
|
|
44
|
+
chatConnection,
|
|
45
|
+
sharedCache,
|
|
46
|
+
roomResponse
|
|
47
|
+
} = params;
|
|
48
|
+
const roomType = roomResponse.room.roomProperties.roomType;
|
|
49
|
+
const RoomControlImpl = ROOM_CONTROL_IMPLEMENTATIONS[roomType];
|
|
50
|
+
if (!RoomControlImpl) {
|
|
51
|
+
throw generateFcrCoreClientError(ErrorModuleCode.FCR_ROOM, DetailErrorCode.UNDEFINED_ERROR, `Unsupported room types: ${roomType}`, new Error(`Unsupported room type: ${roomType}`));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// 创建聊天室控制
|
|
55
|
+
const chatRoomControl = new FcrChatRoomControlImpl(scene, chatConnection, sharedCache, false);
|
|
56
|
+
|
|
57
|
+
// 创建房间控制实例
|
|
58
|
+
return new RoomControlImpl(engine, scene, apiService, config, sharedCache, chatConnection, chatRoomControl);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* 验证房间类型是否受支持
|
|
63
|
+
* @param roomType 房间类型
|
|
64
|
+
* @returns 是否支持
|
|
65
|
+
*/
|
|
66
|
+
static isRoomTypeSupported(roomType) {
|
|
67
|
+
return roomType in ROOM_CONTROL_IMPLEMENTATIONS;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* 获取所有支持的房间类型
|
|
72
|
+
* @returns 支持的房间类型数组
|
|
73
|
+
*/
|
|
74
|
+
static getSupportedRoomTypes() {
|
|
75
|
+
return Object.keys(ROOM_CONTROL_IMPLEMENTATIONS).map(key => parseInt(key, 10));
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
import "core-js/modules/es.array.push.js";
|
|
2
|
+
import "core-js/modules/esnext.function.metadata.js";
|
|
3
|
+
import "core-js/modules/esnext.symbol.metadata.js";
|
|
4
|
+
let _initProto, _startRoomSessionDecs, _stopRoomSessionDecs, _acceptRoomSessionDecs, _rejectRoomSessionDecs;
|
|
5
|
+
import "core-js/modules/es.json.stringify.js";
|
|
6
|
+
import "core-js/modules/esnext.iterator.constructor.js";
|
|
7
|
+
import "core-js/modules/esnext.iterator.map.js";
|
|
8
|
+
import "core-js/modules/esnext.map.delete-all.js";
|
|
9
|
+
import "core-js/modules/esnext.map.emplace.js";
|
|
10
|
+
import "core-js/modules/esnext.map.every.js";
|
|
11
|
+
import "core-js/modules/esnext.map.filter.js";
|
|
12
|
+
import "core-js/modules/esnext.map.find.js";
|
|
13
|
+
import "core-js/modules/esnext.map.find-key.js";
|
|
14
|
+
import "core-js/modules/esnext.map.includes.js";
|
|
15
|
+
import "core-js/modules/esnext.map.key-of.js";
|
|
16
|
+
import "core-js/modules/esnext.map.map-keys.js";
|
|
17
|
+
import "core-js/modules/esnext.map.map-values.js";
|
|
18
|
+
import "core-js/modules/esnext.map.merge.js";
|
|
19
|
+
import "core-js/modules/esnext.map.reduce.js";
|
|
20
|
+
import "core-js/modules/esnext.map.some.js";
|
|
21
|
+
import "core-js/modules/esnext.map.update.js";
|
|
22
|
+
function _applyDecs(e, t, r, n, o, a) { function i(e, t, r) { return function (n, o) { return r && r(n), e[t].call(n, o); }; } function c(e, t) { for (var r = 0; r < e.length; r++) e[r].call(t); return t; } function s(e, t, r, n) { if ("function" != typeof e && (n || void 0 !== e)) throw new TypeError(t + " must " + (r || "be") + " a function" + (n ? "" : " or undefined")); return e; } function applyDec(e, t, r, n, o, a, c, u, l, f, p, d, h) { function m(e) { if (!h(e)) throw new TypeError("Attempted to access private element on non-instance"); } var y, v = t[0], g = t[3], b = !u; if (!b) { r || Array.isArray(v) || (v = [v]); var w = {}, S = [], A = 3 === o ? "get" : 4 === o || d ? "set" : "value"; f ? (p || d ? w = { get: _setFunctionName(function () { return g(this); }, n, "get"), set: function (e) { t[4](this, e); } } : w[A] = g, p || _setFunctionName(w[A], n, 2 === o ? "" : A)) : p || (w = Object.getOwnPropertyDescriptor(e, n)); } for (var P = e, j = v.length - 1; j >= 0; j -= r ? 2 : 1) { var D = v[j], E = r ? v[j - 1] : void 0, I = {}, O = { kind: ["field", "accessor", "method", "getter", "setter", "class"][o], name: n, metadata: a, addInitializer: function (e, t) { if (e.v) throw Error("attempted to call addInitializer after decoration was finished"); s(t, "An initializer", "be", !0), c.push(t); }.bind(null, I) }; try { if (b) (y = s(D.call(E, P, O), "class decorators", "return")) && (P = y);else { var k, F; O.static = l, O.private = f, f ? 2 === o ? k = function (e) { return m(e), w.value; } : (o < 4 && (k = i(w, "get", m)), 3 !== o && (F = i(w, "set", m))) : (k = function (e) { return e[n]; }, (o < 2 || 4 === o) && (F = function (e, t) { e[n] = t; })); var N = O.access = { has: f ? h.bind() : function (e) { return n in e; } }; if (k && (N.get = k), F && (N.set = F), P = D.call(E, d ? { get: w.get, set: w.set } : w[A], O), d) { if ("object" == typeof P && P) (y = s(P.get, "accessor.get")) && (w.get = y), (y = s(P.set, "accessor.set")) && (w.set = y), (y = s(P.init, "accessor.init")) && S.push(y);else if (void 0 !== P) throw new TypeError("accessor decorators must return an object with get, set, or init properties or void 0"); } else s(P, (p ? "field" : "method") + " decorators", "return") && (p ? S.push(P) : w[A] = P); } } finally { I.v = !0; } } return (p || d) && u.push(function (e, t) { for (var r = S.length - 1; r >= 0; r--) t = S[r].call(e, t); return t; }), p || b || (f ? d ? u.push(i(w, "get"), i(w, "set")) : u.push(2 === o ? w[A] : i.call.bind(w[A])) : Object.defineProperty(e, n, w)), P; } function u(e, t) { return Object.defineProperty(e, Symbol.metadata || Symbol.for("Symbol.metadata"), { configurable: !0, enumerable: !0, value: t }); } if (arguments.length >= 6) var l = a[Symbol.metadata || Symbol.for("Symbol.metadata")]; var f = Object.create(null == l ? null : l), p = function (e, t, r, n) { var o, a, i = [], s = function (t) { return _checkInRHS(t) === e; }, u = new Map(); function l(e) { e && i.push(c.bind(null, e)); } for (var f = 0; f < t.length; f++) { var p = t[f]; if (Array.isArray(p)) { var d = p[1], h = p[2], m = p.length > 3, y = 16 & d, v = !!(8 & d), g = 0 == (d &= 7), b = h + "/" + v; if (!g && !m) { var w = u.get(b); if (!0 === w || 3 === w && 4 !== d || 4 === w && 3 !== d) throw Error("Attempted to decorate a public method/accessor that has the same name as a previously decorated public method/accessor. This is not currently supported by the decorators plugin. Property name was: " + h); u.set(b, !(d > 2) || d); } applyDec(v ? e : e.prototype, p, y, m ? "#" + h : _toPropertyKey(h), d, n, v ? a = a || [] : o = o || [], i, v, m, g, 1 === d, v && m ? s : r); } } return l(o), l(a), i; }(e, t, o, f); return r.length || u(e, f), { e: p, get c() { var t = []; return r.length && [u(applyDec(e, [r], n, e.name, 5, f, t), f), c.bind(null, t, e)]; } }; }
|
|
23
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
24
|
+
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
25
|
+
function _setFunctionName(e, t, n) { "symbol" == typeof t && (t = (t = t.description) ? "[" + t + "]" : ""); try { Object.defineProperty(e, "name", { configurable: !0, value: n ? n + " " + t : t }); } catch (e) {} return e; }
|
|
26
|
+
function _checkInRHS(e) { if (Object(e) !== e) throw TypeError("right-hand side of 'in' should be an object, got " + (null !== e ? typeof e : "null")); return e; }
|
|
27
|
+
import { DetailErrorCode } from '../../imports';
|
|
28
|
+
import { ActionWhenTaskFail, AgoraObservable, AgoraScheduler, Duration, md5, trace } from '../../imports';
|
|
29
|
+
import { fcrPrivilegeUserRoleArraySchema, fcrRoomSessionParamsSchema, fcrSessionBaseSchema, stringKeyUnknownValueSchema, stringSchema } from '../../schema';
|
|
30
|
+
import { FcrPrivilegeUserRoleToStringMap, FcrReturnCode } from '../../type';
|
|
31
|
+
import { generateFcrCoreServerError } from '../../utilities/error';
|
|
32
|
+
import { createLogger, generateLogObserver } from '../../utilities/logger';
|
|
33
|
+
import validateParams from '../../utilities/validate-params';
|
|
34
|
+
import { ROOM_MESSAGE_COMMANDS } from '../helpers';
|
|
35
|
+
/**
|
|
36
|
+
* @internal
|
|
37
|
+
*/
|
|
38
|
+
export class FcrRoomSessionControlImpl {
|
|
39
|
+
static {
|
|
40
|
+
[_initProto] = _applyDecs(this, [[_startRoomSessionDecs, 2, "startRoomSession"], [_stopRoomSessionDecs, 2, "stopRoomSession"], [_acceptRoomSessionDecs, 2, "acceptRoomSession"], [_rejectRoomSessionDecs, 2, "rejectRoomSession"]], []).e;
|
|
41
|
+
}
|
|
42
|
+
//@internal
|
|
43
|
+
[(_startRoomSessionDecs = [trace(['params', 'targetRoles']), validateParams(fcrRoomSessionParamsSchema, fcrPrivilegeUserRoleArraySchema.optional())], _stopRoomSessionDecs = [trace(['sessionId']), validateParams(stringSchema)], _acceptRoomSessionDecs = [trace(['session', 'cause']), validateParams(fcrSessionBaseSchema, stringKeyUnknownValueSchema.optional())], _rejectRoomSessionDecs = [trace(['session', 'cause']), validateParams(fcrSessionBaseSchema, stringKeyUnknownValueSchema.optional())], "logger")] = (_initProto(this), createLogger({
|
|
44
|
+
prefix: 'FcrRoomSessionControlImpl'
|
|
45
|
+
}));
|
|
46
|
+
//@internal
|
|
47
|
+
_observable = new AgoraObservable();
|
|
48
|
+
//@internal
|
|
49
|
+
_taskInterval = Duration.second(1);
|
|
50
|
+
//@internal
|
|
51
|
+
|
|
52
|
+
//@internal
|
|
53
|
+
_scheduleMap = new Map();
|
|
54
|
+
//@internal
|
|
55
|
+
_receivedMap = new Map();
|
|
56
|
+
constructor(_roomControl, _api, _userId) {
|
|
57
|
+
this._roomControl = _roomControl;
|
|
58
|
+
this._api = _api;
|
|
59
|
+
this._userId = _userId;
|
|
60
|
+
this._executeTask = this._executeTask.bind(this);
|
|
61
|
+
this._addLogObserver();
|
|
62
|
+
this._roomControl.addObserver({
|
|
63
|
+
onRoomMessageReceived: this._handleRoomMessage.bind(this)
|
|
64
|
+
});
|
|
65
|
+
this._task = AgoraScheduler.shared.addPollingTask(this._executeTask, this._taskInterval, true, () => ActionWhenTaskFail.CONTINUE);
|
|
66
|
+
}
|
|
67
|
+
async startRoomSession(params, targetRoles) {
|
|
68
|
+
try {
|
|
69
|
+
const session = {
|
|
70
|
+
sessionId: md5(`${this._userId}${Date.now()}`),
|
|
71
|
+
sessionKey: params.sessionKey,
|
|
72
|
+
payload: params.payload,
|
|
73
|
+
duration: params.duration,
|
|
74
|
+
sender: this._userId,
|
|
75
|
+
targetRoles: targetRoles ? targetRoles.map(role => FcrPrivilegeUserRoleToStringMap[role]) : undefined
|
|
76
|
+
};
|
|
77
|
+
const {
|
|
78
|
+
data: {
|
|
79
|
+
interval
|
|
80
|
+
}
|
|
81
|
+
} = await this._api.updateRoomSession({
|
|
82
|
+
userId: this._userId,
|
|
83
|
+
sessionId: session.sessionId,
|
|
84
|
+
sessionKey: session.sessionKey,
|
|
85
|
+
duration: session.duration,
|
|
86
|
+
payload: session.payload,
|
|
87
|
+
targetId: this._roomControl.getRoomInfo().roomId,
|
|
88
|
+
targetRoles: session.targetRoles
|
|
89
|
+
});
|
|
90
|
+
const nextTs = Date.now() + interval;
|
|
91
|
+
this._scheduleMap.set(session.sessionId, {
|
|
92
|
+
...params,
|
|
93
|
+
targetRoles: session.targetRoles,
|
|
94
|
+
nextTs,
|
|
95
|
+
startTs: Date.now()
|
|
96
|
+
});
|
|
97
|
+
this.logger.info(`[RoomSession] put into session schedule: ${session.sessionId}, next ts: ${nextTs}, remain: ${nextTs - Date.now()}ms`);
|
|
98
|
+
return session.sessionId;
|
|
99
|
+
} catch (e) {
|
|
100
|
+
throw generateFcrCoreServerError(DetailErrorCode.LOCAL_HTTP_REQUEST_FAILED, 'start room session failed', e);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
stopRoomSession(sessionId) {
|
|
104
|
+
return this._scheduleMap.delete(sessionId);
|
|
105
|
+
}
|
|
106
|
+
async acceptRoomSession(session, cause) {
|
|
107
|
+
if (this._isSessionExpired(session)) {
|
|
108
|
+
throw generateFcrCoreServerError(DetailErrorCode.EXPIRED, 'accept room session failed: session expired', new Error());
|
|
109
|
+
}
|
|
110
|
+
try {
|
|
111
|
+
await this._api.deleteRoomSession({
|
|
112
|
+
userId: this._userId,
|
|
113
|
+
sessionId: session.sessionId,
|
|
114
|
+
sessionKey: session.sessionKey,
|
|
115
|
+
receiverIds: [session.senderId],
|
|
116
|
+
target: 2,
|
|
117
|
+
action: 1,
|
|
118
|
+
payload: {
|
|
119
|
+
cause
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
return FcrReturnCode.SUCCESS;
|
|
123
|
+
} catch (e) {
|
|
124
|
+
throw generateFcrCoreServerError(DetailErrorCode.LOCAL_HTTP_REQUEST_FAILED, 'accept room session failed', e);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
async rejectRoomSession(session, cause) {
|
|
128
|
+
if (this._isSessionExpired(session)) {
|
|
129
|
+
throw generateFcrCoreServerError(DetailErrorCode.EXPIRED, 'reject room session failed: session expired', new Error());
|
|
130
|
+
}
|
|
131
|
+
try {
|
|
132
|
+
await this._api.deleteRoomSession({
|
|
133
|
+
userId: this._userId,
|
|
134
|
+
sessionId: session.sessionId,
|
|
135
|
+
sessionKey: session.sessionKey,
|
|
136
|
+
receiverIds: [session.senderId],
|
|
137
|
+
target: 2,
|
|
138
|
+
action: 2,
|
|
139
|
+
payload: {
|
|
140
|
+
cause
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
return FcrReturnCode.SUCCESS;
|
|
144
|
+
} catch (e) {
|
|
145
|
+
throw generateFcrCoreServerError(DetailErrorCode.LOCAL_HTTP_REQUEST_FAILED, 'reject room session failed', e);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
addObserver(observer) {
|
|
149
|
+
this._observable.addObserver(observer);
|
|
150
|
+
}
|
|
151
|
+
removeObserver(observer) {
|
|
152
|
+
this._observable.removeObserver(observer);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
//@internal
|
|
156
|
+
async _executeTask() {
|
|
157
|
+
// ping sessions (sender side)
|
|
158
|
+
for (const key of this._scheduleMap.keys()) {
|
|
159
|
+
const params = this._scheduleMap.get(key);
|
|
160
|
+
const session = {
|
|
161
|
+
sessionId: key,
|
|
162
|
+
sessionKey: params.sessionKey,
|
|
163
|
+
payload: params.payload,
|
|
164
|
+
duration: params.duration,
|
|
165
|
+
senderId: this._userId,
|
|
166
|
+
timestamp: params.startTs,
|
|
167
|
+
targetRoles: params.targetRoles,
|
|
168
|
+
interval: 0
|
|
169
|
+
};
|
|
170
|
+
if (this._isSessionExpired(session)) {
|
|
171
|
+
this.logger.info(`room session expired, removed: ${session.sessionId}`);
|
|
172
|
+
this._scheduleMap.delete(session.sessionId);
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
// check timeout
|
|
176
|
+
if (params.nextTs < Date.now()) {
|
|
177
|
+
this.logger.info(`ping session: ${session.sessionId}`);
|
|
178
|
+
try {
|
|
179
|
+
const {
|
|
180
|
+
data: {
|
|
181
|
+
interval
|
|
182
|
+
}
|
|
183
|
+
} = await this._api.updateRoomSession({
|
|
184
|
+
userId: this._userId,
|
|
185
|
+
sessionId: session.sessionId,
|
|
186
|
+
sessionKey: session.sessionKey,
|
|
187
|
+
duration: params.duration,
|
|
188
|
+
payload: session.payload,
|
|
189
|
+
targetRoles: session.targetRoles,
|
|
190
|
+
targetId: this._roomControl.getRoomInfo().roomId
|
|
191
|
+
});
|
|
192
|
+
const nextTs = Date.now() + interval;
|
|
193
|
+
if (this._scheduleMap.has(session.sessionId)) {
|
|
194
|
+
this._scheduleMap.set(session.sessionId, {
|
|
195
|
+
...params,
|
|
196
|
+
nextTs
|
|
197
|
+
});
|
|
198
|
+
this.logger.info(`[RoomSession] refresh session schedule: ${session.sessionId}, next ts: ${nextTs}`);
|
|
199
|
+
}
|
|
200
|
+
} catch (e) {
|
|
201
|
+
this.logger.error(`ping session failed: ${e}`);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
// clear expired sessions (receiver side)
|
|
206
|
+
for (const key of this._receivedMap.keys()) {
|
|
207
|
+
const session = this._receivedMap.get(key);
|
|
208
|
+
if (this._isSessionExpired(session)) {
|
|
209
|
+
this._receivedMap.delete(key);
|
|
210
|
+
this.logger.info(`delete session callback: ${key}`);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
//@internal
|
|
216
|
+
async _handleRoomMessage(roomId, message) {
|
|
217
|
+
const {
|
|
218
|
+
senderId,
|
|
219
|
+
payload,
|
|
220
|
+
cmd
|
|
221
|
+
} = message;
|
|
222
|
+
const data = payload;
|
|
223
|
+
if (cmd === ROOM_MESSAGE_COMMANDS.ROOM_SESSION_REQUEST) {
|
|
224
|
+
const session = {
|
|
225
|
+
sessionId: data.sessionUuid,
|
|
226
|
+
sessionKey: data.sessionKey,
|
|
227
|
+
senderId,
|
|
228
|
+
duration: data.duration,
|
|
229
|
+
timestamp: message.timestamp,
|
|
230
|
+
interval: data.interval,
|
|
231
|
+
payload: data.payload
|
|
232
|
+
};
|
|
233
|
+
const sessionCache = this._receivedMap.get(session.sessionId);
|
|
234
|
+
if (sessionCache) {
|
|
235
|
+
session.timestamp = sessionCache.timestamp;
|
|
236
|
+
}
|
|
237
|
+
if (!this._isSessionExpired(session)) {
|
|
238
|
+
if (!this._receivedMap.has(session.sessionId)) {
|
|
239
|
+
this.logger.info(`[RoomSession] received room session request ${JSON.stringify(session)}`);
|
|
240
|
+
this._observable.notifyObservers('onRoomSessionReceived', roomId, session);
|
|
241
|
+
}
|
|
242
|
+
this._receivedMap.set(session.sessionId, session);
|
|
243
|
+
}
|
|
244
|
+
} else if (cmd === ROOM_MESSAGE_COMMANDS.ROOM_SESSION_ACCEPT) {
|
|
245
|
+
// TODO: BUG FIXSME: onRoomSessionAccepted 和 onRoomSessionRejected 两个事件, apaas private doc 描述的是监听 AgoraRteEngine.onSceneMessageReceived
|
|
246
|
+
// 但是点对点消息实际上触发的是 AgoraRteEngine.onPeerMessageReceived 事件. 所以这里并不会收到 cmd === ROOM_SESSION_ACCEPT 和 ROOM_SESSION_REJECT 的消息.
|
|
247
|
+
if (data.action === 1) {
|
|
248
|
+
if (this._scheduleMap.has(data.sessionUuid)) {
|
|
249
|
+
const session = this._scheduleMap.get(data.sessionUuid);
|
|
250
|
+
const sessionResponse = {
|
|
251
|
+
sessionId: data.sessionUuid,
|
|
252
|
+
sessionKey: data.sessionKey,
|
|
253
|
+
responderId: senderId,
|
|
254
|
+
// FIXME: session may be lost when the client refreshes
|
|
255
|
+
// get payload from original session
|
|
256
|
+
payload: session.payload ?? {},
|
|
257
|
+
cause: data.payload?.cause ?? {}
|
|
258
|
+
};
|
|
259
|
+
this.logger.info(`[RoomSession] received room session accepted ${JSON.stringify(sessionResponse)}`);
|
|
260
|
+
this._scheduleMap.delete(data.sessionUuid);
|
|
261
|
+
this._observable.notifyObservers('onRoomSessionAccepted', roomId, sessionResponse);
|
|
262
|
+
}
|
|
263
|
+
} else if (data.action === 2) {
|
|
264
|
+
if (this._scheduleMap.has(data.sessionUuid)) {
|
|
265
|
+
const session = this._scheduleMap.get(data.sessionUuid);
|
|
266
|
+
const sessionResponse = {
|
|
267
|
+
sessionId: data.sessionUuid,
|
|
268
|
+
sessionKey: data.sessionKey,
|
|
269
|
+
responderId: senderId,
|
|
270
|
+
// FIXME: session may be lost when the client refreshes
|
|
271
|
+
// get payload from original session
|
|
272
|
+
payload: session.payload ?? {},
|
|
273
|
+
cause: data.payload?.cause ?? {}
|
|
274
|
+
};
|
|
275
|
+
this.logger.info(`[RoomSession] received room session rejected ${JSON.stringify(sessionResponse)}`);
|
|
276
|
+
if (this._scheduleMap.has(data.sessionUuid)) {
|
|
277
|
+
this._scheduleMap.delete(data.sessionUuid);
|
|
278
|
+
this._observable.notifyObservers('onRoomSessionRejected', roomId, sessionResponse);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
//@internal
|
|
286
|
+
_isSessionExpired(session) {
|
|
287
|
+
return session.timestamp + session.duration * Duration.second(1) < Date.now();
|
|
288
|
+
}
|
|
289
|
+
_addLogObserver() {
|
|
290
|
+
this.addObserver(generateLogObserver(this.logger, [['onRoomSessionAccepted', ['roomId', 'response']], ['onRoomSessionRejected', ['roomId', 'response']], ['onRoomSessionReceived', ['roomId', 'session']]]));
|
|
291
|
+
}
|
|
292
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import "core-js/modules/esnext.map.delete-all.js";
|
|
2
|
+
import "core-js/modules/esnext.map.emplace.js";
|
|
3
|
+
import "core-js/modules/esnext.map.every.js";
|
|
4
|
+
import "core-js/modules/esnext.map.filter.js";
|
|
5
|
+
import "core-js/modules/esnext.map.find.js";
|
|
6
|
+
import "core-js/modules/esnext.map.find-key.js";
|
|
7
|
+
import "core-js/modules/esnext.map.includes.js";
|
|
8
|
+
import "core-js/modules/esnext.map.key-of.js";
|
|
9
|
+
import "core-js/modules/esnext.map.map-keys.js";
|
|
10
|
+
import "core-js/modules/esnext.map.map-values.js";
|
|
11
|
+
import "core-js/modules/esnext.map.merge.js";
|
|
12
|
+
import "core-js/modules/esnext.map.reduce.js";
|
|
13
|
+
import "core-js/modules/esnext.map.some.js";
|
|
14
|
+
import "core-js/modules/esnext.map.update.js";
|
|
15
|
+
export class FcrRoomCache {
|
|
16
|
+
_platformMapByUserId = new Map();
|
|
17
|
+
_avatarMapByUserId = new Map();
|
|
18
|
+
getUserPlatform = userId => {
|
|
19
|
+
return this._platformMapByUserId.get(userId);
|
|
20
|
+
};
|
|
21
|
+
getUserAvatar = userId => {
|
|
22
|
+
return this._avatarMapByUserId.get(userId);
|
|
23
|
+
};
|
|
24
|
+
setUserPlatform = (userId, platform) => {
|
|
25
|
+
this._platformMapByUserId.set(userId, platform);
|
|
26
|
+
};
|
|
27
|
+
setUserAvatar = (userId, avatar) => {
|
|
28
|
+
this._avatarMapByUserId.set(userId, avatar);
|
|
29
|
+
};
|
|
30
|
+
deleteUserPlatform = userId => {
|
|
31
|
+
this._platformMapByUserId.delete(userId);
|
|
32
|
+
};
|
|
33
|
+
deleteUserAvatar = userId => {
|
|
34
|
+
this._avatarMapByUserId.delete(userId);
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
export class FcrSharedCache {
|
|
38
|
+
_roomCache = new Map();
|
|
39
|
+
getRoomCache = roomId => {
|
|
40
|
+
let roomCache = this._roomCache.get(roomId);
|
|
41
|
+
if (!roomCache) {
|
|
42
|
+
roomCache = new FcrRoomCache();
|
|
43
|
+
this._roomCache.set(roomId, roomCache);
|
|
44
|
+
}
|
|
45
|
+
return roomCache;
|
|
46
|
+
};
|
|
47
|
+
}
|