livekit-client 2.18.10 → 2.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/livekit-client.e2ee.worker.js.map +1 -1
- package/dist/livekit-client.e2ee.worker.mjs.map +1 -1
- package/dist/livekit-client.esm.mjs +720 -430
- package/dist/livekit-client.esm.mjs.map +1 -1
- package/dist/livekit-client.pt.worker.js.map +1 -1
- package/dist/livekit-client.pt.worker.mjs.map +1 -1
- package/dist/livekit-client.umd.js +1 -1
- package/dist/livekit-client.umd.js.map +1 -1
- package/dist/src/room/RTCEngine.d.ts +0 -3
- package/dist/src/room/RTCEngine.d.ts.map +1 -1
- package/dist/src/room/Room.d.ts +4 -2
- package/dist/src/room/Room.d.ts.map +1 -1
- package/dist/src/room/participant/LocalParticipant.d.ts +5 -13
- package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
- package/dist/src/room/participant/RemoteParticipant.d.ts +5 -1
- package/dist/src/room/participant/RemoteParticipant.d.ts.map +1 -1
- package/dist/src/room/rpc/client/RpcClientManager.d.ts +39 -0
- package/dist/src/room/rpc/client/RpcClientManager.d.ts.map +1 -0
- package/dist/src/room/rpc/client/events.d.ts +8 -0
- package/dist/src/room/rpc/client/events.d.ts.map +1 -0
- package/dist/src/room/rpc/index.d.ts +6 -0
- package/dist/src/room/rpc/index.d.ts.map +1 -0
- package/dist/src/room/rpc/server/RpcServerManager.d.ts +44 -0
- package/dist/src/room/rpc/server/RpcServerManager.d.ts.map +1 -0
- package/dist/src/room/rpc/server/events.d.ts +8 -0
- package/dist/src/room/rpc/server/events.d.ts.map +1 -0
- package/dist/src/room/{rpc.d.ts → rpc/utils.d.ts} +34 -4
- package/dist/src/room/rpc/utils.d.ts.map +1 -0
- package/dist/src/room/utils.d.ts.map +1 -1
- package/dist/src/version.d.ts +8 -0
- package/dist/src/version.d.ts.map +1 -1
- package/dist/ts4.2/room/RTCEngine.d.ts +0 -3
- package/dist/ts4.2/room/Room.d.ts +4 -2
- package/dist/ts4.2/room/participant/LocalParticipant.d.ts +5 -13
- package/dist/ts4.2/room/participant/RemoteParticipant.d.ts +5 -1
- package/dist/ts4.2/room/rpc/client/RpcClientManager.d.ts +43 -0
- package/dist/ts4.2/room/rpc/client/events.d.ts +8 -0
- package/dist/ts4.2/room/rpc/index.d.ts +7 -0
- package/dist/ts4.2/room/rpc/server/RpcServerManager.d.ts +44 -0
- package/dist/ts4.2/room/rpc/server/events.d.ts +8 -0
- package/dist/ts4.2/room/{rpc.d.ts → rpc/utils.d.ts} +34 -4
- package/dist/ts4.2/version.d.ts +8 -0
- package/package.json +1 -1
- package/src/room/RTCEngine.ts +0 -26
- package/src/room/Room.ts +83 -81
- package/src/room/participant/LocalParticipant.ts +16 -180
- package/src/room/participant/RemoteParticipant.ts +9 -0
- package/src/room/rpc/client/RpcClientManager.test.ts +430 -0
- package/src/room/rpc/client/RpcClientManager.ts +269 -0
- package/src/room/rpc/client/events.ts +9 -0
- package/src/room/rpc/index.ts +14 -0
- package/src/room/rpc/server/RpcServerManager.test.ts +471 -0
- package/src/room/rpc/server/RpcServerManager.ts +293 -0
- package/src/room/rpc/server/events.ts +9 -0
- package/src/room/{rpc.ts → rpc/utils.ts} +49 -8
- package/src/room/utils.ts +2 -1
- package/src/version.ts +10 -0
- package/dist/src/room/rpc.d.ts.map +0 -1
- package/src/room/rpc.test.ts +0 -301
|
@@ -22,6 +22,10 @@ export default class RemoteParticipant extends Participant {
|
|
|
22
22
|
* const track = await remoteParticipant.dataTracks.getDeferred("data track name"); */
|
|
23
23
|
dataTracks: DeferrableMap<RemoteDataTrack['info']['name'], RemoteDataTrack>;
|
|
24
24
|
signalClient: SignalClient;
|
|
25
|
+
/** A version number indicating the set of features that the report participant's client supports.
|
|
26
|
+
* @internal
|
|
27
|
+
**/
|
|
28
|
+
clientProtocol: number;
|
|
25
29
|
private volumeMap;
|
|
26
30
|
private audioOutput?;
|
|
27
31
|
/** @internal */
|
|
@@ -31,7 +35,7 @@ export default class RemoteParticipant extends Participant {
|
|
|
31
35
|
remoteParticipant: string;
|
|
32
36
|
};
|
|
33
37
|
/** @internal */
|
|
34
|
-
constructor(signalClient: SignalClient, sid: string, identity?: string, name?: string, metadata?: string, attributes?: Record<string, string>, loggerOptions?: LoggerOptions, kind?: ParticipantKind, remoteDataTracks?: Array<RemoteDataTrack
|
|
38
|
+
constructor(signalClient: SignalClient, sid: string, identity?: string, name?: string, metadata?: string, attributes?: Record<string, string>, loggerOptions?: LoggerOptions, kind?: ParticipantKind, remoteDataTracks?: Array<RemoteDataTrack>, clientProtocol?: number);
|
|
35
39
|
protected addTrackPublication(publication: RemoteTrackPublication): void;
|
|
36
40
|
getTrackPublication(source: Track.Source): RemoteTrackPublication | undefined;
|
|
37
41
|
getTrackPublicationByName(name: string): RemoteTrackPublication | undefined;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type TypedEmitter from 'typed-emitter';
|
|
2
|
+
import type { StructuredLogger } from '../../../logger';
|
|
3
|
+
import type { TextStreamReader } from '../../data-stream/incoming/StreamReader';
|
|
4
|
+
import type OutgoingDataStreamManager from '../../data-stream/outgoing/OutgoingDataStreamManager';
|
|
5
|
+
import type Participant from '../../participant/Participant';
|
|
6
|
+
import type { PerformRpcParams } from '../utils';
|
|
7
|
+
import { RpcError } from '../utils';
|
|
8
|
+
import type { RpcClientManagerCallbacks } from './events';
|
|
9
|
+
declare const RpcClientManager_base: new () => TypedEmitter<RpcClientManagerCallbacks>;
|
|
10
|
+
/**
|
|
11
|
+
* Manages the client (caller) side of RPC: sending requests, tracking pending
|
|
12
|
+
* ack/response state, and handling incoming ack/response packets.
|
|
13
|
+
* @internal
|
|
14
|
+
*/
|
|
15
|
+
export default class RpcClientManager extends RpcClientManager_base {
|
|
16
|
+
private log;
|
|
17
|
+
private outgoingDataStreamManager;
|
|
18
|
+
private getRemoteParticipantClientProtocol;
|
|
19
|
+
private getServerVersion;
|
|
20
|
+
private pendingAcks;
|
|
21
|
+
private pendingResponses;
|
|
22
|
+
constructor(log: StructuredLogger, outgoingDataStreamManager: OutgoingDataStreamManager, getRemoteParticipantClientProtocol: (identity: Participant['identity']) => number, getServerVersion: () => string | undefined);
|
|
23
|
+
performRpc({ destinationIdentity, method, payload, responseTimeout: responseTimeoutMs, }: PerformRpcParams): Promise<[
|
|
24
|
+
id: string,
|
|
25
|
+
completionPromise: Promise<string>
|
|
26
|
+
]>;
|
|
27
|
+
private publishRpcRequest;
|
|
28
|
+
/**
|
|
29
|
+
* Handle an incoming data stream containing an RPC response payload.
|
|
30
|
+
* @internal
|
|
31
|
+
*/
|
|
32
|
+
handleIncomingDataStream(reader: TextStreamReader, senderIdentity: Participant['identity'], attributes: Record<string, string>): Promise<void>;
|
|
33
|
+
/** @internal */
|
|
34
|
+
handleIncomingRpcResponseSuccess(requestId: string, payload: string): void;
|
|
35
|
+
/** @internal */
|
|
36
|
+
handleIncomingRpcResponseFailure(requestId: string, error: RpcError): void;
|
|
37
|
+
/** @internal */
|
|
38
|
+
handleIncomingRpcAck(requestId: string): void;
|
|
39
|
+
/** @internal */
|
|
40
|
+
handleParticipantDisconnected(participantIdentity: string): void;
|
|
41
|
+
}
|
|
42
|
+
export {};
|
|
43
|
+
//# sourceMappingURL=RpcClientManager.d.ts.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { default as RpcClientManager } from './client/RpcClientManager';
|
|
2
|
+
export type { RpcClientManagerCallbacks } from './client/events';
|
|
3
|
+
export { default as RpcServerManager } from './server/RpcServerManager';
|
|
4
|
+
export type { RpcServerManagerCallbacks } from './server/events';
|
|
5
|
+
export type { PerformRpcParams, RpcInvocationData } from './utils';
|
|
6
|
+
export { RPC_REQUEST_DATA_STREAM_TOPIC, RPC_RESPONSE_DATA_STREAM_TOPIC, RpcRequestAttrs, RpcError, byteLength, truncateBytes } from './utils';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { RpcRequest } from '@livekit/protocol';
|
|
2
|
+
import type TypedEmitter from 'typed-emitter';
|
|
3
|
+
import type { StructuredLogger } from '../../../logger';
|
|
4
|
+
import type { TextStreamReader } from '../../data-stream/incoming/StreamReader';
|
|
5
|
+
import type OutgoingDataStreamManager from '../../data-stream/outgoing/OutgoingDataStreamManager';
|
|
6
|
+
import type Participant from '../../participant/Participant';
|
|
7
|
+
import type { RpcInvocationData } from '../utils';
|
|
8
|
+
import type { RpcServerManagerCallbacks } from './events';
|
|
9
|
+
declare const RpcServerManager_base: new () => TypedEmitter<RpcServerManagerCallbacks>;
|
|
10
|
+
/**
|
|
11
|
+
* Manages the server (handler) side of RPC: processing incoming requests,
|
|
12
|
+
* managing registered method handlers, and sending responses.
|
|
13
|
+
* @internal
|
|
14
|
+
*/
|
|
15
|
+
export default class RpcServerManager extends RpcServerManager_base {
|
|
16
|
+
private log;
|
|
17
|
+
private outgoingDataStreamManager;
|
|
18
|
+
private getRemoteParticipantClientProtocol;
|
|
19
|
+
private rpcHandlers;
|
|
20
|
+
constructor(log: StructuredLogger, outgoingDataStreamManager: OutgoingDataStreamManager, getRemoteParticipantClientProtocol: (identity: Participant['identity']) => number);
|
|
21
|
+
registerRpcMethod(method: string, handler: (data: RpcInvocationData) => Promise<string>): void;
|
|
22
|
+
unregisterRpcMethod(method: string): void;
|
|
23
|
+
/**
|
|
24
|
+
* Handle an incoming RPCRequest message containing a payload.
|
|
25
|
+
* This handles "version 1" of rpc requests.
|
|
26
|
+
* @internal
|
|
27
|
+
*/
|
|
28
|
+
handleIncomingRpcRequest(callerIdentity: string, rpcRequest: RpcRequest): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Handle an incoming data stream containing a RPC request payload.
|
|
31
|
+
* This handles "version 2" of rpc requests.
|
|
32
|
+
* @internal
|
|
33
|
+
*/
|
|
34
|
+
handleIncomingDataStream(reader: TextStreamReader, callerIdentity: Participant['identity'], dataStreamAttrs: Record<string, string>): Promise<void>;
|
|
35
|
+
private publishRpcAck;
|
|
36
|
+
private publishRpcResponsePacket;
|
|
37
|
+
/**
|
|
38
|
+
* Send a successful RPC response payload, choosing the transport based on
|
|
39
|
+
* the caller's client protocol version.
|
|
40
|
+
*/
|
|
41
|
+
private publishRpcResponse;
|
|
42
|
+
}
|
|
43
|
+
export {};
|
|
44
|
+
//# sourceMappingURL=RpcServerManager.d.ts.map
|
|
@@ -49,6 +49,7 @@ export declare class RpcError extends Error {
|
|
|
49
49
|
static MAX_DATA_BYTES: number;
|
|
50
50
|
code: number;
|
|
51
51
|
data?: string;
|
|
52
|
+
cause?: unknown;
|
|
52
53
|
/**
|
|
53
54
|
* Creates an error object with the given code and message, plus an optional data payload.
|
|
54
55
|
*
|
|
@@ -56,7 +57,9 @@ export declare class RpcError extends Error {
|
|
|
56
57
|
*
|
|
57
58
|
* Error codes 1001-1999 are reserved for built-in errors (see RpcError.ErrorCode for their meanings).
|
|
58
59
|
*/
|
|
59
|
-
constructor(code: number, message: string, data?: string
|
|
60
|
+
constructor(code: number, message: string, data?: string, options?: {
|
|
61
|
+
cause?: unknown;
|
|
62
|
+
});
|
|
60
63
|
/**
|
|
61
64
|
* @internal
|
|
62
65
|
*/
|
|
@@ -87,9 +90,36 @@ export declare class RpcError extends Error {
|
|
|
87
90
|
*
|
|
88
91
|
* @internal
|
|
89
92
|
*/
|
|
90
|
-
static builtIn(key: keyof typeof RpcError.ErrorCode, data?: string
|
|
93
|
+
static builtIn(key: keyof typeof RpcError.ErrorCode, data?: string, options?: {
|
|
94
|
+
cause?: unknown;
|
|
95
|
+
}): RpcError;
|
|
91
96
|
}
|
|
92
|
-
export declare const
|
|
97
|
+
export declare const MAX_V1_PAYLOAD_BYTES = 15360;
|
|
98
|
+
/**
|
|
99
|
+
* Topic used for v2 RPC request data streams.
|
|
100
|
+
* @internal
|
|
101
|
+
*/
|
|
102
|
+
export declare const RPC_REQUEST_DATA_STREAM_TOPIC = "lk.rpc_request";
|
|
103
|
+
/**
|
|
104
|
+
* Topic used for v2 RPC response data streams.
|
|
105
|
+
* @internal
|
|
106
|
+
*/
|
|
107
|
+
export declare const RPC_RESPONSE_DATA_STREAM_TOPIC = "lk.rpc_response";
|
|
108
|
+
/** @internal */
|
|
109
|
+
export declare enum RpcRequestAttrs {
|
|
110
|
+
RPC_REQUEST_ID = "lk.rpc_request_id",
|
|
111
|
+
RPC_REQUEST_METHOD = "lk.rpc_request_method",
|
|
112
|
+
RPC_REQUEST_RESPONSE_TIMEOUT_MS = "lk.rpc_request_response_timeout_ms",
|
|
113
|
+
RPC_REQUEST_VERSION = "lk.rpc_request_version"
|
|
114
|
+
}
|
|
115
|
+
/** Initial version of rpc which uses RpcRequest / RpcResponse messages.
|
|
116
|
+
* @internal
|
|
117
|
+
**/
|
|
118
|
+
export declare const RPC_VERSION_V1 = 1;
|
|
119
|
+
/** Rpc version backed by data streams instead of RpcRequest / RpcResponse.
|
|
120
|
+
* @internal
|
|
121
|
+
**/
|
|
122
|
+
export declare const RPC_VERSION_V2 = 2;
|
|
93
123
|
/**
|
|
94
124
|
* @internal
|
|
95
125
|
*/
|
|
@@ -98,4 +128,4 @@ export declare function byteLength(str: string): number;
|
|
|
98
128
|
* @internal
|
|
99
129
|
*/
|
|
100
130
|
export declare function truncateBytes(str: string, maxBytes: number): string;
|
|
101
|
-
//# sourceMappingURL=
|
|
131
|
+
//# sourceMappingURL=utils.d.ts.map
|
package/dist/ts4.2/version.d.ts
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
1
|
export declare const version: string;
|
|
2
2
|
export declare const protocolVersion = 17;
|
|
3
|
+
/** Initial client protocol. */
|
|
4
|
+
export declare const CLIENT_PROTOCOL_DEFAULT = 0;
|
|
5
|
+
/** Replaces RPC v1 protocol with a v2 data streams based one to support unlimited request /
|
|
6
|
+
* response payload length. */
|
|
7
|
+
export declare const CLIENT_PROTOCOL_DATA_STREAM_RPC = 1;
|
|
8
|
+
/** The client protocol version indicates what level of support that the client has for
|
|
9
|
+
* client <-> client api interactions. */
|
|
10
|
+
export declare const clientProtocol = 1;
|
|
3
11
|
//# sourceMappingURL=version.d.ts.map
|
package/package.json
CHANGED
package/src/room/RTCEngine.ts
CHANGED
|
@@ -26,7 +26,6 @@ import {
|
|
|
26
26
|
Room as RoomModel,
|
|
27
27
|
RoomMovedResponse,
|
|
28
28
|
RpcAck,
|
|
29
|
-
RpcResponse,
|
|
30
29
|
ServerInfo,
|
|
31
30
|
SessionDescription,
|
|
32
31
|
SignalTarget,
|
|
@@ -79,7 +78,6 @@ import {
|
|
|
79
78
|
UnexpectedConnectionState,
|
|
80
79
|
} from './errors';
|
|
81
80
|
import { EngineEvent } from './events';
|
|
82
|
-
import { RpcError } from './rpc';
|
|
83
81
|
import CriticalTimers from './timers';
|
|
84
82
|
import type LocalTrack from './track/LocalTrack';
|
|
85
83
|
import type LocalTrackPublication from './track/LocalTrackPublication';
|
|
@@ -1464,30 +1462,6 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
1464
1462
|
});
|
|
1465
1463
|
};
|
|
1466
1464
|
|
|
1467
|
-
/** @internal */
|
|
1468
|
-
async publishRpcResponse(
|
|
1469
|
-
destinationIdentity: string,
|
|
1470
|
-
requestId: string,
|
|
1471
|
-
payload: string | null,
|
|
1472
|
-
error: RpcError | null,
|
|
1473
|
-
) {
|
|
1474
|
-
const packet = new DataPacket({
|
|
1475
|
-
destinationIdentities: [destinationIdentity],
|
|
1476
|
-
kind: DataPacket_Kind.RELIABLE,
|
|
1477
|
-
value: {
|
|
1478
|
-
case: 'rpcResponse',
|
|
1479
|
-
value: new RpcResponse({
|
|
1480
|
-
requestId,
|
|
1481
|
-
value: error
|
|
1482
|
-
? { case: 'error', value: error.toProto() }
|
|
1483
|
-
: { case: 'payload', value: payload ?? '' },
|
|
1484
|
-
}),
|
|
1485
|
-
},
|
|
1486
|
-
});
|
|
1487
|
-
|
|
1488
|
-
await this.sendDataPacket(packet, DataChannelKind.RELIABLE);
|
|
1489
|
-
}
|
|
1490
|
-
|
|
1491
1465
|
/** @internal */
|
|
1492
1466
|
async publishRpcAck(destinationIdentity: string, requestId: string) {
|
|
1493
1467
|
const packet = new DataPacket({
|
package/src/room/Room.ts
CHANGED
|
@@ -48,6 +48,7 @@ import { PacketTrailerManager } from '../packetTrailer/PacketTrailerManager';
|
|
|
48
48
|
import { isPacketTrailerSupported } from '../packetTrailer/utils';
|
|
49
49
|
import TypedPromise from '../utils/TypedPromise';
|
|
50
50
|
import { getBrowser } from '../utils/browserParser';
|
|
51
|
+
import { CLIENT_PROTOCOL_DEFAULT } from '../version';
|
|
51
52
|
import { BackOffStrategy } from './BackOffStrategy';
|
|
52
53
|
import DeviceManager from './DeviceManager';
|
|
53
54
|
import RTCEngine, { DataChannelKind, type RegionStrategy } from './RTCEngine';
|
|
@@ -81,7 +82,14 @@ import LocalParticipant from './participant/LocalParticipant';
|
|
|
81
82
|
import Participant from './participant/Participant';
|
|
82
83
|
import { type ConnectionQuality, ParticipantKind } from './participant/Participant';
|
|
83
84
|
import RemoteParticipant from './participant/RemoteParticipant';
|
|
84
|
-
import {
|
|
85
|
+
import {
|
|
86
|
+
RPC_REQUEST_DATA_STREAM_TOPIC,
|
|
87
|
+
RPC_RESPONSE_DATA_STREAM_TOPIC,
|
|
88
|
+
RpcClientManager,
|
|
89
|
+
RpcError,
|
|
90
|
+
type RpcInvocationData,
|
|
91
|
+
RpcServerManager,
|
|
92
|
+
} from './rpc';
|
|
85
93
|
import CriticalTimers from './timers';
|
|
86
94
|
import LocalAudioTrack from './track/LocalAudioTrack';
|
|
87
95
|
import type LocalTrack from './track/LocalTrack';
|
|
@@ -221,7 +229,9 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
|
221
229
|
|
|
222
230
|
private outgoingDataTrackManager: OutgoingDataTrackManager;
|
|
223
231
|
|
|
224
|
-
private
|
|
232
|
+
private rpcClientManager: RpcClientManager;
|
|
233
|
+
|
|
234
|
+
private rpcServerManager: RpcServerManager;
|
|
225
235
|
|
|
226
236
|
get hasE2EESetup(): boolean {
|
|
227
237
|
return this.e2eeManager !== undefined;
|
|
@@ -301,15 +311,36 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
|
301
311
|
.finally(() => this.outgoingDataTrackManager.handlePacketSendComplete(handle));
|
|
302
312
|
});
|
|
303
313
|
|
|
314
|
+
this.registerRpcDataStreamHandler();
|
|
315
|
+
|
|
316
|
+
this.rpcClientManager = new RpcClientManager(
|
|
317
|
+
this.log,
|
|
318
|
+
this.outgoingDataStreamManager,
|
|
319
|
+
this.getRemoteParticipantClientProtocol,
|
|
320
|
+
() => this.engine.latestJoinResponse?.serverInfo?.version,
|
|
321
|
+
);
|
|
322
|
+
this.rpcClientManager.on('sendDataPacket', ({ packet }) => {
|
|
323
|
+
this.engine?.sendDataPacket(packet, DataChannelKind.RELIABLE);
|
|
324
|
+
});
|
|
325
|
+
this.rpcServerManager = new RpcServerManager(
|
|
326
|
+
this.log,
|
|
327
|
+
this.outgoingDataStreamManager,
|
|
328
|
+
this.getRemoteParticipantClientProtocol,
|
|
329
|
+
);
|
|
330
|
+
this.rpcServerManager.on('sendDataPacket', ({ packet }) => {
|
|
331
|
+
this.engine?.sendDataPacket(packet, DataChannelKind.RELIABLE);
|
|
332
|
+
});
|
|
333
|
+
|
|
304
334
|
this.disconnectLock = new Mutex();
|
|
305
335
|
this.localParticipant = new LocalParticipant(
|
|
306
336
|
'',
|
|
307
337
|
'',
|
|
308
338
|
this.engine,
|
|
309
339
|
this.options,
|
|
310
|
-
this.rpcHandlers,
|
|
311
340
|
this.outgoingDataStreamManager,
|
|
312
341
|
this.outgoingDataTrackManager,
|
|
342
|
+
this.rpcClientManager,
|
|
343
|
+
this.rpcServerManager,
|
|
313
344
|
);
|
|
314
345
|
|
|
315
346
|
this.setupPacketTrailer();
|
|
@@ -400,12 +431,7 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
|
400
431
|
* Other errors thrown in your handler will not be transmitted as-is, and will instead arrive to the caller as `1500` ("Application Error").
|
|
401
432
|
*/
|
|
402
433
|
registerRpcMethod(method: string, handler: (data: RpcInvocationData) => Promise<string>) {
|
|
403
|
-
|
|
404
|
-
throw Error(
|
|
405
|
-
`RPC handler already registered for method ${method}, unregisterRpcMethod before trying to register again`,
|
|
406
|
-
);
|
|
407
|
-
}
|
|
408
|
-
this.rpcHandlers.set(method, handler);
|
|
434
|
+
this.rpcServerManager.registerRpcMethod(method, handler);
|
|
409
435
|
}
|
|
410
436
|
|
|
411
437
|
/**
|
|
@@ -414,7 +440,7 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
|
414
440
|
* @param method - The name of the RPC method to unregister
|
|
415
441
|
*/
|
|
416
442
|
unregisterRpcMethod(method: string) {
|
|
417
|
-
this.
|
|
443
|
+
this.rpcServerManager.unregisterRpcMethod(method);
|
|
418
444
|
}
|
|
419
445
|
|
|
420
446
|
/**
|
|
@@ -1873,7 +1899,7 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
|
1873
1899
|
});
|
|
1874
1900
|
this.emit(RoomEvent.ParticipantDisconnected, participant);
|
|
1875
1901
|
participant.setDisconnected();
|
|
1876
|
-
this.
|
|
1902
|
+
this.rpcClientManager.handleParticipantDisconnected(participant.identity);
|
|
1877
1903
|
}
|
|
1878
1904
|
|
|
1879
1905
|
// updates are sent only when there's a change to speaker ordering
|
|
@@ -2017,14 +2043,31 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
|
2017
2043
|
this.handleDataStream(packet, encryptionType);
|
|
2018
2044
|
} else if (packet.value.case === 'rpcRequest') {
|
|
2019
2045
|
const rpc = packet.value.value;
|
|
2020
|
-
this.handleIncomingRpcRequest(
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2046
|
+
this.rpcServerManager.handleIncomingRpcRequest(packet.participantIdentity, rpc);
|
|
2047
|
+
} else if (packet.value.case === 'rpcResponse') {
|
|
2048
|
+
const rpcResponse = packet.value.value;
|
|
2049
|
+
switch (rpcResponse.value.case) {
|
|
2050
|
+
case 'payload':
|
|
2051
|
+
this.rpcClientManager.handleIncomingRpcResponseSuccess(
|
|
2052
|
+
rpcResponse.requestId,
|
|
2053
|
+
rpcResponse.value.value,
|
|
2054
|
+
);
|
|
2055
|
+
break;
|
|
2056
|
+
case 'error':
|
|
2057
|
+
this.rpcClientManager.handleIncomingRpcResponseFailure(
|
|
2058
|
+
rpcResponse.requestId,
|
|
2059
|
+
RpcError.fromProto(rpcResponse.value.value),
|
|
2060
|
+
);
|
|
2061
|
+
break;
|
|
2062
|
+
default:
|
|
2063
|
+
this.log.warn(
|
|
2064
|
+
`Unknown rpcResponse.value.case: ${rpcResponse.value.case}`,
|
|
2065
|
+
this.logContext,
|
|
2066
|
+
);
|
|
2067
|
+
break;
|
|
2068
|
+
}
|
|
2069
|
+
} else if (packet.value.case === 'rpcAck') {
|
|
2070
|
+
this.rpcClientManager.handleIncomingRpcAck(packet.value.value.requestId);
|
|
2028
2071
|
}
|
|
2029
2072
|
};
|
|
2030
2073
|
|
|
@@ -2093,68 +2136,6 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
|
2093
2136
|
this.incomingDataStreamManager.handleDataStreamPacket(packet, encryptionType);
|
|
2094
2137
|
};
|
|
2095
2138
|
|
|
2096
|
-
private async handleIncomingRpcRequest(
|
|
2097
|
-
callerIdentity: string,
|
|
2098
|
-
requestId: string,
|
|
2099
|
-
method: string,
|
|
2100
|
-
payload: string,
|
|
2101
|
-
responseTimeout: number,
|
|
2102
|
-
version: number,
|
|
2103
|
-
) {
|
|
2104
|
-
await this.engine.publishRpcAck(callerIdentity, requestId);
|
|
2105
|
-
|
|
2106
|
-
if (version !== 1) {
|
|
2107
|
-
await this.engine.publishRpcResponse(
|
|
2108
|
-
callerIdentity,
|
|
2109
|
-
requestId,
|
|
2110
|
-
null,
|
|
2111
|
-
RpcError.builtIn('UNSUPPORTED_VERSION'),
|
|
2112
|
-
);
|
|
2113
|
-
return;
|
|
2114
|
-
}
|
|
2115
|
-
|
|
2116
|
-
const handler = this.rpcHandlers.get(method);
|
|
2117
|
-
|
|
2118
|
-
if (!handler) {
|
|
2119
|
-
await this.engine.publishRpcResponse(
|
|
2120
|
-
callerIdentity,
|
|
2121
|
-
requestId,
|
|
2122
|
-
null,
|
|
2123
|
-
RpcError.builtIn('UNSUPPORTED_METHOD'),
|
|
2124
|
-
);
|
|
2125
|
-
return;
|
|
2126
|
-
}
|
|
2127
|
-
|
|
2128
|
-
let responseError: RpcError | null = null;
|
|
2129
|
-
let responsePayload: string | null = null;
|
|
2130
|
-
|
|
2131
|
-
try {
|
|
2132
|
-
const response = await handler({
|
|
2133
|
-
requestId,
|
|
2134
|
-
callerIdentity,
|
|
2135
|
-
payload,
|
|
2136
|
-
responseTimeout,
|
|
2137
|
-
});
|
|
2138
|
-
if (byteLength(response) > MAX_PAYLOAD_BYTES) {
|
|
2139
|
-
responseError = RpcError.builtIn('RESPONSE_PAYLOAD_TOO_LARGE');
|
|
2140
|
-
this.log.warn(`RPC Response payload too large for ${method}`);
|
|
2141
|
-
} else {
|
|
2142
|
-
responsePayload = response;
|
|
2143
|
-
}
|
|
2144
|
-
} catch (error) {
|
|
2145
|
-
if (error instanceof RpcError) {
|
|
2146
|
-
responseError = error;
|
|
2147
|
-
} else {
|
|
2148
|
-
this.log.warn(
|
|
2149
|
-
`Uncaught error returned by RPC handler for ${method}. Returning APPLICATION_ERROR instead.`,
|
|
2150
|
-
error,
|
|
2151
|
-
);
|
|
2152
|
-
responseError = RpcError.builtIn('APPLICATION_ERROR');
|
|
2153
|
-
}
|
|
2154
|
-
}
|
|
2155
|
-
await this.engine.publishRpcResponse(callerIdentity, requestId, responsePayload, responseError);
|
|
2156
|
-
}
|
|
2157
|
-
|
|
2158
2139
|
bufferedSegments: Map<string, TranscriptionSegmentModel> = new Map();
|
|
2159
2140
|
|
|
2160
2141
|
private handleAudioPlaybackStarted = () => {
|
|
@@ -2500,6 +2481,27 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
|
2500
2481
|
}
|
|
2501
2482
|
}
|
|
2502
2483
|
|
|
2484
|
+
private getRemoteParticipantClientProtocol = (identity: Participant['identity']) => {
|
|
2485
|
+
return this.remoteParticipants.get(identity)?.clientProtocol ?? CLIENT_PROTOCOL_DEFAULT;
|
|
2486
|
+
};
|
|
2487
|
+
|
|
2488
|
+
private registerRpcDataStreamHandler() {
|
|
2489
|
+
this.incomingDataStreamManager.registerTextStreamHandler(
|
|
2490
|
+
RPC_REQUEST_DATA_STREAM_TOPIC,
|
|
2491
|
+
async (reader, { identity }) => {
|
|
2492
|
+
const attributes = reader.info.attributes ?? {};
|
|
2493
|
+
await this.rpcServerManager.handleIncomingDataStream(reader, identity, attributes);
|
|
2494
|
+
},
|
|
2495
|
+
);
|
|
2496
|
+
this.incomingDataStreamManager.registerTextStreamHandler(
|
|
2497
|
+
RPC_RESPONSE_DATA_STREAM_TOPIC,
|
|
2498
|
+
async (reader, { identity }) => {
|
|
2499
|
+
const attributes = reader.info.attributes ?? {};
|
|
2500
|
+
await this.rpcClientManager.handleIncomingDataStream(reader, identity, attributes);
|
|
2501
|
+
},
|
|
2502
|
+
);
|
|
2503
|
+
}
|
|
2504
|
+
|
|
2503
2505
|
private registerConnectionReconcile() {
|
|
2504
2506
|
this.clearConnectionReconcile();
|
|
2505
2507
|
let consecutiveFailures = 0;
|