@livekit/rtc-node 0.10.3 → 0.11.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/README.md +54 -2
- package/build.rs +1 -1
- package/dist/audio_frame.d.ts +1 -1
- package/dist/audio_frame.d.ts.map +1 -1
- package/dist/audio_frame.js +4 -4
- package/dist/audio_frame.js.map +1 -1
- package/dist/audio_resampler.d.ts.map +1 -1
- package/dist/audio_resampler.js +8 -7
- package/dist/audio_resampler.js.map +1 -1
- package/dist/audio_source.d.ts.map +1 -1
- package/dist/audio_source.js +8 -4
- package/dist/audio_source.js.map +1 -1
- package/dist/audio_stream.d.ts +1 -1
- package/dist/audio_stream.d.ts.map +1 -1
- package/dist/audio_stream.js +4 -3
- package/dist/audio_stream.js.map +1 -1
- package/dist/e2ee.d.ts.map +1 -1
- package/dist/e2ee.js +25 -25
- package/dist/e2ee.js.map +1 -1
- package/dist/ffi_client.d.ts +3 -3
- package/dist/ffi_client.d.ts.map +1 -1
- package/dist/ffi_client.js +9 -7
- package/dist/ffi_client.js.map +1 -1
- package/dist/index.d.ts +29 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +34 -4
- package/dist/index.js.map +1 -1
- package/dist/napi/native.d.ts +1 -0
- package/dist/participant.d.ts +52 -6
- package/dist/participant.d.ts.map +1 -1
- package/dist/participant.js +155 -32
- package/dist/participant.js.map +1 -1
- package/dist/proto/audio_frame_pb.d.ts +451 -526
- package/dist/proto/audio_frame_pb.d.ts.map +1 -1
- package/dist/proto/audio_frame_pb.js +200 -1179
- package/dist/proto/audio_frame_pb.js.map +1 -1
- package/dist/proto/e2ee_pb.d.ts +264 -333
- package/dist/proto/e2ee_pb.d.ts.map +1 -1
- package/dist/proto/e2ee_pb.js +136 -810
- package/dist/proto/e2ee_pb.js.map +1 -1
- package/dist/proto/ffi_pb.d.ts +175 -129
- package/dist/proto/ffi_pb.d.ts.map +1 -1
- package/dist/proto/ffi_pb.js +58 -395
- package/dist/proto/ffi_pb.js.map +1 -1
- package/dist/proto/handle_pb.d.ts +14 -13
- package/dist/proto/handle_pb.d.ts.map +1 -1
- package/dist/proto/handle_pb.js +8 -39
- package/dist/proto/handle_pb.js.map +1 -1
- package/dist/proto/participant_pb.d.ts +54 -52
- package/dist/proto/participant_pb.d.ts.map +1 -1
- package/dist/proto/participant_pb.js +18 -90
- package/dist/proto/participant_pb.js.map +1 -1
- package/dist/proto/room_pb.d.ts +1042 -1187
- package/dist/proto/room_pb.d.ts.map +1 -1
- package/dist/proto/room_pb.js +470 -2938
- package/dist/proto/room_pb.js.map +1 -1
- package/dist/proto/rpc_pb.d.ts +235 -0
- package/dist/proto/rpc_pb.d.ts.map +1 -0
- package/dist/proto/rpc_pb.js +74 -0
- package/dist/proto/rpc_pb.js.map +1 -0
- package/dist/proto/stats_pb.d.ts +738 -800
- package/dist/proto/stats_pb.d.ts.map +1 -1
- package/dist/proto/stats_pb.js +218 -1960
- package/dist/proto/stats_pb.js.map +1 -1
- package/dist/proto/track_pb.d.ts +225 -258
- package/dist/proto/track_pb.d.ts.map +1 -1
- package/dist/proto/track_pb.js +98 -591
- package/dist/proto/track_pb.js.map +1 -1
- package/dist/proto/video_frame_pb.d.ts +357 -390
- package/dist/proto/video_frame_pb.d.ts.map +1 -1
- package/dist/proto/video_frame_pb.js +137 -790
- package/dist/proto/video_frame_pb.js.map +1 -1
- package/dist/room.d.ts +21 -7
- package/dist/room.d.ts.map +1 -1
- package/dist/room.js +134 -54
- package/dist/room.js.map +1 -1
- package/dist/rpc.d.ts +78 -0
- package/dist/rpc.d.ts.map +1 -0
- package/dist/rpc.js +69 -0
- package/dist/rpc.js.map +1 -0
- package/dist/track.d.ts.map +1 -1
- package/dist/track.js +7 -3
- package/dist/track.js.map +1 -1
- package/dist/track_publication.d.ts.map +1 -1
- package/dist/track_publication.js +3 -2
- package/dist/track_publication.js.map +1 -1
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +2 -0
- package/dist/version.js.map +1 -0
- package/dist/video_frame.d.ts +2 -2
- package/dist/video_frame.d.ts.map +1 -1
- package/dist/video_frame.js +47 -25
- package/dist/video_frame.js.map +1 -1
- package/dist/video_source.d.ts.map +1 -1
- package/dist/video_source.js +4 -3
- package/dist/video_source.js.map +1 -1
- package/dist/video_stream.d.ts +1 -1
- package/dist/video_stream.d.ts.map +1 -1
- package/dist/video_stream.js +7 -3
- package/dist/video_stream.js.map +1 -1
- package/package.json +13 -10
- package/src/audio_frame.ts +6 -6
- package/src/audio_resampler.ts +10 -9
- package/src/audio_source.ts +9 -8
- package/src/audio_stream.ts +7 -6
- package/src/e2ee.ts +34 -34
- package/src/ffi_client.ts +23 -10
- package/src/index.ts +61 -2
- package/src/napi/native.d.ts +1 -0
- package/src/nodejs.rs +6 -3
- package/src/participant.ts +219 -55
- package/src/proto/audio_frame_pb.ts +562 -1279
- package/src/proto/e2ee_pb.ts +365 -886
- package/src/proto/ffi_pb.ts +206 -405
- package/src/proto/handle_pb.ts +21 -35
- package/src/proto/participant_pb.ts +71 -112
- package/src/proto/room_pb.ts +1284 -2995
- package/src/proto/rpc_pb.ts +310 -0
- package/src/proto/stats_pb.ts +1028 -1947
- package/src/proto/track_pb.ts +287 -621
- package/src/proto/video_frame_pb.ts +445 -905
- package/src/room.ts +181 -75
- package/src/rpc.ts +121 -0
- package/src/track.ts +8 -7
- package/src/track_publication.ts +5 -4
- package/src/version.ts +1 -0
- package/src/video_frame.ts +54 -27
- package/src/video_source.ts +7 -6
- package/src/video_stream.ts +7 -6
- package/dist/utils.d.ts +0 -7
- package/dist/utils.d.ts.map +0 -1
- package/dist/utils.js +0 -48
- package/dist/utils.js.map +0 -1
- package/src/utils.test.ts +0 -47
- package/src/utils.ts +0 -44
package/src/participant.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: 2024 LiveKit, Inc.
|
|
2
2
|
//
|
|
3
3
|
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
import { create } from '@bufbuild/protobuf';
|
|
4
5
|
import { FfiClient, FfiHandle } from './ffi_client.js';
|
|
5
6
|
import type { OwnedParticipant, ParticipantInfo, ParticipantKind } from './proto/participant_pb.js';
|
|
6
|
-
import {
|
|
7
|
-
ChatMessage as ChatMessageModel,
|
|
7
|
+
import type {
|
|
8
8
|
PublishDataCallback,
|
|
9
9
|
PublishDataResponse,
|
|
10
10
|
PublishSipDtmfCallback,
|
|
@@ -26,23 +26,38 @@ import {
|
|
|
26
26
|
UnpublishTrackResponse,
|
|
27
27
|
} from './proto/room_pb.js';
|
|
28
28
|
import {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
29
|
+
ChatMessageSchema,
|
|
30
|
+
EditChatMessageRequestSchema,
|
|
31
|
+
PublishDataRequestSchema,
|
|
32
|
+
PublishSipDtmfRequestSchema,
|
|
33
|
+
PublishTrackRequestSchema,
|
|
34
|
+
PublishTranscriptionRequestSchema,
|
|
35
|
+
SendChatMessageRequestSchema,
|
|
36
|
+
SetLocalAttributesRequestSchema,
|
|
37
|
+
SetLocalMetadataRequestSchema,
|
|
38
|
+
SetLocalNameRequestSchema,
|
|
39
|
+
UnpublishTrackRequestSchema,
|
|
40
40
|
} from './proto/room_pb.js';
|
|
41
|
+
import { TranscriptionSegmentSchema } from './proto/room_pb.js';
|
|
42
|
+
import {
|
|
43
|
+
PerformRpcRequestSchema,
|
|
44
|
+
RegisterRpcMethodRequestSchema,
|
|
45
|
+
RpcMethodInvocationResponseRequestSchema,
|
|
46
|
+
UnregisterRpcMethodRequestSchema,
|
|
47
|
+
} from './proto/rpc_pb.js';
|
|
48
|
+
import type {
|
|
49
|
+
PerformRpcCallback,
|
|
50
|
+
PerformRpcResponse,
|
|
51
|
+
RegisterRpcMethodResponse,
|
|
52
|
+
RpcMethodInvocationResponseResponse,
|
|
53
|
+
UnregisterRpcMethodResponse,
|
|
54
|
+
} from './proto/rpc_pb.js';
|
|
55
|
+
import { type PerformRpcParams, RpcError, type RpcInvocationData } from './rpc.js';
|
|
41
56
|
import type { LocalTrack } from './track.js';
|
|
42
57
|
import type { RemoteTrackPublication, TrackPublication } from './track_publication.js';
|
|
43
58
|
import { LocalTrackPublication } from './track_publication.js';
|
|
44
59
|
import type { Transcription } from './transcription.js';
|
|
45
|
-
import { ChatMessage } from './types.js';
|
|
60
|
+
import type { ChatMessage } from './types.js';
|
|
46
61
|
|
|
47
62
|
export abstract class Participant {
|
|
48
63
|
/** @internal */
|
|
@@ -54,8 +69,8 @@ export abstract class Participant {
|
|
|
54
69
|
trackPublications = new Map<string, TrackPublication>();
|
|
55
70
|
|
|
56
71
|
constructor(owned_info: OwnedParticipant) {
|
|
57
|
-
this.info = owned_info.info
|
|
58
|
-
this.ffi_handle = new FfiHandle(owned_info.handle
|
|
72
|
+
this.info = owned_info.info!;
|
|
73
|
+
this.ffi_handle = new FfiHandle(owned_info.handle!.id);
|
|
59
74
|
}
|
|
60
75
|
|
|
61
76
|
get sid(): string {
|
|
@@ -100,10 +115,12 @@ export type DataPublishOptions = {
|
|
|
100
115
|
};
|
|
101
116
|
|
|
102
117
|
export class LocalParticipant extends Participant {
|
|
118
|
+
private rpcHandlers: Map<string, (data: RpcInvocationData) => Promise<string>> = new Map();
|
|
119
|
+
|
|
103
120
|
trackPublications: Map<string, LocalTrackPublication> = new Map();
|
|
104
121
|
|
|
105
122
|
async publishData(data: Uint8Array, options: DataPublishOptions) {
|
|
106
|
-
const req =
|
|
123
|
+
const req = create(PublishDataRequestSchema, {
|
|
107
124
|
localParticipantHandle: this.ffi_handle.handle,
|
|
108
125
|
dataPtr: FfiClient.instance.retrievePtr(data),
|
|
109
126
|
dataLen: BigInt(data.byteLength),
|
|
@@ -126,7 +143,7 @@ export class LocalParticipant extends Participant {
|
|
|
126
143
|
}
|
|
127
144
|
|
|
128
145
|
async publishDtmf(code: number, digit: string) {
|
|
129
|
-
const req =
|
|
146
|
+
const req = create(PublishSipDtmfRequestSchema, {
|
|
130
147
|
localParticipantHandle: this.ffi_handle.handle,
|
|
131
148
|
code,
|
|
132
149
|
digit,
|
|
@@ -146,19 +163,18 @@ export class LocalParticipant extends Participant {
|
|
|
146
163
|
}
|
|
147
164
|
|
|
148
165
|
async publishTranscription(transcription: Transcription) {
|
|
149
|
-
const req =
|
|
166
|
+
const req = create(PublishTranscriptionRequestSchema, {
|
|
150
167
|
localParticipantHandle: this.ffi_handle.handle,
|
|
151
168
|
participantIdentity: transcription.participantIdentity,
|
|
152
|
-
segments: transcription.segments.map(
|
|
153
|
-
(
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
}),
|
|
169
|
+
segments: transcription.segments.map((s) =>
|
|
170
|
+
create(TranscriptionSegmentSchema, {
|
|
171
|
+
id: s.id,
|
|
172
|
+
text: s.text,
|
|
173
|
+
startTime: s.startTime,
|
|
174
|
+
endTime: s.endTime,
|
|
175
|
+
final: s.final,
|
|
176
|
+
language: s.language,
|
|
177
|
+
}),
|
|
162
178
|
),
|
|
163
179
|
trackId: transcription.trackSid,
|
|
164
180
|
});
|
|
@@ -177,7 +193,7 @@ export class LocalParticipant extends Participant {
|
|
|
177
193
|
}
|
|
178
194
|
|
|
179
195
|
async updateMetadata(metadata: string) {
|
|
180
|
-
const req =
|
|
196
|
+
const req = create(SetLocalMetadataRequestSchema, {
|
|
181
197
|
localParticipantHandle: this.ffi_handle.handle,
|
|
182
198
|
metadata: metadata,
|
|
183
199
|
});
|
|
@@ -192,6 +208,11 @@ export class LocalParticipant extends Participant {
|
|
|
192
208
|
}
|
|
193
209
|
|
|
194
210
|
/**
|
|
211
|
+
* Sends a chat message to participants in the room
|
|
212
|
+
*
|
|
213
|
+
* @param text - The text content of the chat message.
|
|
214
|
+
* @param destinationIdentities - An optional array of recipient identities to whom the message will be sent. If omitted, the message is broadcast to all participants.
|
|
215
|
+
* @param senderIdentity - An optional identity of the sender. If omitted, the default sender identity is used.
|
|
195
216
|
*
|
|
196
217
|
*/
|
|
197
218
|
async sendChatMessage(
|
|
@@ -199,7 +220,7 @@ export class LocalParticipant extends Participant {
|
|
|
199
220
|
destinationIdentities?: Array<string>,
|
|
200
221
|
senderIdentity?: string,
|
|
201
222
|
): Promise<ChatMessage> {
|
|
202
|
-
const req =
|
|
223
|
+
const req = create(SendChatMessageRequestSchema, {
|
|
203
224
|
localParticipantHandle: this.ffi_handle.handle,
|
|
204
225
|
message: text,
|
|
205
226
|
destinationIdentities,
|
|
@@ -214,20 +235,15 @@ export class LocalParticipant extends Participant {
|
|
|
214
235
|
return ev.message.case == 'chatMessage' && ev.message.value.asyncId == res.asyncId;
|
|
215
236
|
});
|
|
216
237
|
|
|
217
|
-
if (cb.
|
|
218
|
-
throw new Error(cb.
|
|
238
|
+
if (cb.message.case !== 'chatMessage') {
|
|
239
|
+
throw new Error(cb.message.value ?? 'Unknown Error');
|
|
219
240
|
}
|
|
220
|
-
const { id, timestamp, editTimestamp, message } = cb.
|
|
241
|
+
const { id, timestamp, editTimestamp, message } = cb.message.value;
|
|
221
242
|
return { id, timestamp: Number(timestamp), editTimestamp: Number(editTimestamp), message };
|
|
222
243
|
}
|
|
223
244
|
|
|
224
245
|
/**
|
|
225
|
-
*
|
|
226
|
-
*
|
|
227
|
-
* @param text - The text content of the chat message.
|
|
228
|
-
* @param destinationIdentities - An optional array of recipient identities to whom the message will be sent. If omitted, the message is broadcast to all participants.
|
|
229
|
-
* @param senderIdentity - An optional identity of the sender. If omitted, the default sender identity is used.
|
|
230
|
-
*
|
|
246
|
+
* @experimental
|
|
231
247
|
*/
|
|
232
248
|
async editChatMessage(
|
|
233
249
|
editText: string,
|
|
@@ -235,13 +251,15 @@ export class LocalParticipant extends Participant {
|
|
|
235
251
|
destinationIdentities?: Array<string>,
|
|
236
252
|
senderIdentity?: string,
|
|
237
253
|
): Promise<ChatMessage> {
|
|
238
|
-
const req =
|
|
254
|
+
const req = create(EditChatMessageRequestSchema, {
|
|
239
255
|
localParticipantHandle: this.ffi_handle.handle,
|
|
240
256
|
editText,
|
|
241
|
-
originalMessage:
|
|
257
|
+
originalMessage: create(ChatMessageSchema, {
|
|
242
258
|
...originalMessage,
|
|
243
259
|
timestamp: BigInt(originalMessage.timestamp),
|
|
244
|
-
editTimestamp:
|
|
260
|
+
editTimestamp: originalMessage.editTimestamp
|
|
261
|
+
? BigInt(originalMessage.editTimestamp)
|
|
262
|
+
: undefined,
|
|
245
263
|
}),
|
|
246
264
|
destinationIdentities,
|
|
247
265
|
senderIdentity,
|
|
@@ -255,15 +273,15 @@ export class LocalParticipant extends Participant {
|
|
|
255
273
|
return ev.message.case == 'chatMessage' && ev.message.value.asyncId == res.asyncId;
|
|
256
274
|
});
|
|
257
275
|
|
|
258
|
-
if (cb.
|
|
259
|
-
throw new Error(cb.
|
|
276
|
+
if (cb.message.case !== 'chatMessage') {
|
|
277
|
+
throw new Error(cb.message.value ?? 'Unknown Error');
|
|
260
278
|
}
|
|
261
|
-
const { id, timestamp, editTimestamp, message } = cb.
|
|
279
|
+
const { id, timestamp, editTimestamp, message } = cb.message.value;
|
|
262
280
|
return { id, timestamp: Number(timestamp), editTimestamp: Number(editTimestamp), message };
|
|
263
281
|
}
|
|
264
282
|
|
|
265
283
|
async updateName(name: string) {
|
|
266
|
-
const req =
|
|
284
|
+
const req = create(SetLocalNameRequestSchema, {
|
|
267
285
|
localParticipantHandle: this.ffi_handle.handle,
|
|
268
286
|
name: name,
|
|
269
287
|
});
|
|
@@ -278,9 +296,11 @@ export class LocalParticipant extends Participant {
|
|
|
278
296
|
}
|
|
279
297
|
|
|
280
298
|
async setAttributes(attributes: Record<string, string>) {
|
|
281
|
-
const req =
|
|
299
|
+
const req = create(SetLocalAttributesRequestSchema, {
|
|
282
300
|
localParticipantHandle: this.ffi_handle.handle,
|
|
283
|
-
attributes: attributes,
|
|
301
|
+
attributes: Array.from(Object.entries(attributes)).map(([key, value]) => {
|
|
302
|
+
return { key, value };
|
|
303
|
+
}),
|
|
284
304
|
});
|
|
285
305
|
|
|
286
306
|
const res = FfiClient.instance.request<SetLocalAttributesResponse>({
|
|
@@ -296,7 +316,7 @@ export class LocalParticipant extends Participant {
|
|
|
296
316
|
track: LocalTrack,
|
|
297
317
|
options: TrackPublishOptions,
|
|
298
318
|
): Promise<LocalTrackPublication> {
|
|
299
|
-
const req =
|
|
319
|
+
const req = create(PublishTrackRequestSchema, {
|
|
300
320
|
localParticipantHandle: this.ffi_handle.handle,
|
|
301
321
|
trackHandle: track.ffi_handle.handle,
|
|
302
322
|
options: options,
|
|
@@ -310,11 +330,11 @@ export class LocalParticipant extends Participant {
|
|
|
310
330
|
return ev.message.case == 'publishTrack' && ev.message.value.asyncId == res.asyncId;
|
|
311
331
|
});
|
|
312
332
|
|
|
313
|
-
if (cb.
|
|
314
|
-
throw new Error(cb.
|
|
333
|
+
if (cb.message.case !== 'publication') {
|
|
334
|
+
throw new Error(cb.message.value ?? 'Unknown Error');
|
|
315
335
|
}
|
|
316
336
|
|
|
317
|
-
const track_publication = new LocalTrackPublication(cb.
|
|
337
|
+
const track_publication = new LocalTrackPublication(cb.message.value!);
|
|
318
338
|
track_publication.track = track;
|
|
319
339
|
this.trackPublications.set(track_publication.sid, track_publication);
|
|
320
340
|
|
|
@@ -322,7 +342,7 @@ export class LocalParticipant extends Participant {
|
|
|
322
342
|
}
|
|
323
343
|
|
|
324
344
|
async unpublishTrack(trackSid: string) {
|
|
325
|
-
const req =
|
|
345
|
+
const req = create(UnpublishTrackRequestSchema, {
|
|
326
346
|
localParticipantHandle: this.ffi_handle.handle,
|
|
327
347
|
trackSid: trackSid,
|
|
328
348
|
});
|
|
@@ -340,9 +360,153 @@ export class LocalParticipant extends Participant {
|
|
|
340
360
|
}
|
|
341
361
|
|
|
342
362
|
const pub = this.trackPublications.get(trackSid);
|
|
343
|
-
pub
|
|
363
|
+
if (pub) {
|
|
364
|
+
pub.track = undefined;
|
|
365
|
+
}
|
|
344
366
|
this.trackPublications.delete(trackSid);
|
|
345
367
|
}
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
* Initiate an RPC call to a remote participant.
|
|
371
|
+
* @param params - Parameters for initiating the RPC call, see {@link PerformRpcParams}
|
|
372
|
+
* @returns A promise that resolves with the response payload or rejects with an error.
|
|
373
|
+
* @throws Error on failure. Details in `message`.
|
|
374
|
+
*/
|
|
375
|
+
async performRpc({
|
|
376
|
+
destinationIdentity,
|
|
377
|
+
method,
|
|
378
|
+
payload,
|
|
379
|
+
responseTimeout,
|
|
380
|
+
}: PerformRpcParams): Promise<string> {
|
|
381
|
+
const req = create(PerformRpcRequestSchema, {
|
|
382
|
+
localParticipantHandle: this.ffi_handle.handle,
|
|
383
|
+
destinationIdentity,
|
|
384
|
+
method,
|
|
385
|
+
payload,
|
|
386
|
+
responseTimeoutMs: responseTimeout,
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
const res = FfiClient.instance.request<PerformRpcResponse>({
|
|
390
|
+
message: { case: 'performRpc', value: req },
|
|
391
|
+
});
|
|
392
|
+
|
|
393
|
+
const cb = await FfiClient.instance.waitFor<PerformRpcCallback>((ev) => {
|
|
394
|
+
return ev.message.case === 'performRpc' && ev.message.value.asyncId === res.asyncId;
|
|
395
|
+
});
|
|
396
|
+
|
|
397
|
+
if (cb.error) {
|
|
398
|
+
throw RpcError.fromProto(cb.error);
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
return cb.payload;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
/**
|
|
405
|
+
* Establishes the participant as a receiver for calls of the specified RPC method.
|
|
406
|
+
* Will overwrite any existing callback for the same method.
|
|
407
|
+
*
|
|
408
|
+
* @param method - The name of the indicated RPC method
|
|
409
|
+
* @param handler - Will be invoked when an RPC request for this method is received
|
|
410
|
+
* @returns A promise that resolves when the method is successfully registered
|
|
411
|
+
*
|
|
412
|
+
* @example
|
|
413
|
+
* ```typescript
|
|
414
|
+
* room.localParticipant?.registerRpcMethod(
|
|
415
|
+
* 'greet',
|
|
416
|
+
* async (data: RpcInvocationData) => {
|
|
417
|
+
* console.log(`Received greeting from ${data.callerIdentity}: ${data.payload}`);
|
|
418
|
+
* return `Hello, ${data.callerIdentity}!`;
|
|
419
|
+
* }
|
|
420
|
+
* );
|
|
421
|
+
* ```
|
|
422
|
+
*
|
|
423
|
+
* See {@link RpcInvocationData} for more details on invocation params.
|
|
424
|
+
*
|
|
425
|
+
* The handler should return a Promise that resolves to a string.
|
|
426
|
+
* If unable to respond within `responseTimeout`, the request will result in an error on the caller's side.
|
|
427
|
+
*
|
|
428
|
+
* You may throw errors of type `RpcError` with a string `message` in the handler,
|
|
429
|
+
* and they will be received on the caller's side with the message intact.
|
|
430
|
+
* Other errors thrown in your handler will not be transmitted as-is, and will instead arrive to the caller as `1500` ("Application Error").
|
|
431
|
+
*/
|
|
432
|
+
registerRpcMethod(method: string, handler: (data: RpcInvocationData) => Promise<string>) {
|
|
433
|
+
this.rpcHandlers.set(method, handler);
|
|
434
|
+
|
|
435
|
+
const req = create(RegisterRpcMethodRequestSchema, {
|
|
436
|
+
localParticipantHandle: this.ffi_handle.handle,
|
|
437
|
+
method,
|
|
438
|
+
});
|
|
439
|
+
|
|
440
|
+
FfiClient.instance.request<RegisterRpcMethodResponse>({
|
|
441
|
+
message: { case: 'registerRpcMethod', value: req },
|
|
442
|
+
});
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
/**
|
|
446
|
+
* Unregisters a previously registered RPC method.
|
|
447
|
+
*
|
|
448
|
+
* @param method - The name of the RPC method to unregister
|
|
449
|
+
*/
|
|
450
|
+
unregisterRpcMethod(method: string) {
|
|
451
|
+
this.rpcHandlers.delete(method);
|
|
452
|
+
|
|
453
|
+
const req = create(UnregisterRpcMethodRequestSchema, {
|
|
454
|
+
localParticipantHandle: this.ffi_handle.handle,
|
|
455
|
+
method,
|
|
456
|
+
});
|
|
457
|
+
|
|
458
|
+
FfiClient.instance.request<UnregisterRpcMethodResponse>({
|
|
459
|
+
message: { case: 'unregisterRpcMethod', value: req },
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
/** @internal */
|
|
464
|
+
async handleRpcMethodInvocation(
|
|
465
|
+
invocationId: bigint,
|
|
466
|
+
method: string,
|
|
467
|
+
requestId: string,
|
|
468
|
+
callerIdentity: string,
|
|
469
|
+
payload: string,
|
|
470
|
+
responseTimeout: number,
|
|
471
|
+
) {
|
|
472
|
+
let responseError: RpcError | null = null;
|
|
473
|
+
let responsePayload: string | null = null;
|
|
474
|
+
|
|
475
|
+
const handler = this.rpcHandlers.get(method);
|
|
476
|
+
|
|
477
|
+
if (!handler) {
|
|
478
|
+
responseError = RpcError.builtIn('UNSUPPORTED_METHOD');
|
|
479
|
+
} else {
|
|
480
|
+
try {
|
|
481
|
+
responsePayload = await handler({ requestId, callerIdentity, payload, responseTimeout });
|
|
482
|
+
} catch (error) {
|
|
483
|
+
if (error instanceof RpcError) {
|
|
484
|
+
responseError = error;
|
|
485
|
+
} else {
|
|
486
|
+
console.warn(
|
|
487
|
+
`Uncaught error returned by RPC handler for ${method}. Returning APPLICATION_ERROR instead.`,
|
|
488
|
+
error,
|
|
489
|
+
);
|
|
490
|
+
responseError = RpcError.builtIn('APPLICATION_ERROR');
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
const req = create(RpcMethodInvocationResponseRequestSchema, {
|
|
496
|
+
localParticipantHandle: this.ffi_handle.handle,
|
|
497
|
+
invocationId,
|
|
498
|
+
error: responseError ? responseError.toProto() : undefined,
|
|
499
|
+
payload: responsePayload ?? undefined,
|
|
500
|
+
});
|
|
501
|
+
|
|
502
|
+
const res = FfiClient.instance.request<RpcMethodInvocationResponseResponse>({
|
|
503
|
+
message: { case: 'rpcMethodInvocationResponse', value: req },
|
|
504
|
+
});
|
|
505
|
+
|
|
506
|
+
if (res.error) {
|
|
507
|
+
console.warn(`error sending rpc method invocation response: ${res.error}`);
|
|
508
|
+
}
|
|
509
|
+
}
|
|
346
510
|
}
|
|
347
511
|
|
|
348
512
|
export class RemoteParticipant extends Participant {
|