@@ -45,6 +45,7 @@ import '../track/local/audio.dart';
45
45
import '../track/local/video.dart' ;
46
46
import '../track/track.dart' ;
47
47
import '../types/other.dart' ;
48
+ import '../types/rpc.dart' ;
48
49
import '../utils.dart' ;
49
50
import 'engine.dart' ;
50
51
@@ -119,6 +120,12 @@ class Room extends DisposableChangeNotifier with EventsEmittable<RoomEvent> {
119
120
// Agents
120
121
final Map <String , DateTime > _transcriptionReceivedTimes = {};
121
122
123
+ // RPC Handlers
124
+ final Map <String , RpcRequestHandler > _rpcHandlers = {};
125
+
126
+ // for testing
127
+ Map <String , RpcRequestHandler > get rpcHandlers => _rpcHandlers;
128
+
122
129
Room ({
123
130
@Deprecated ('deprecated, please use connectOptions in room.connect()' )
124
131
ConnectOptions connectOptions = const ConnectOptions (),
@@ -141,6 +148,8 @@ class Room extends DisposableChangeNotifier with EventsEmittable<RoomEvent> {
141
148
notifyListeners ();
142
149
});
143
150
151
+ _setupRpcListeners ();
152
+
144
153
onDispose (() async {
145
154
// clean up routine
146
155
await _cleanUp ();
@@ -1129,3 +1138,54 @@ extension RoomHardwareManagementMethods on Room {
1129
1138
events.emit (const AudioPlaybackStatusChanged (isPlaying: false ));
1130
1139
}
1131
1140
}
1141
+
1142
+ extension RoomRPCMethods on Room {
1143
+ void _setupRpcListeners () {
1144
+ // listen for incoming requests
1145
+ _engineListener
1146
+ ..on < EngineRPCRequestReceivedEvent > ((event) async {
1147
+ final request = event.request;
1148
+ await _localParticipant? .handleIncomingRpcRequest (
1149
+ event.identity,
1150
+ request.id,
1151
+ request.method,
1152
+ request.payload,
1153
+ request.responseTimeoutMs,
1154
+ request.version,
1155
+ );
1156
+ })
1157
+ ..on < EngineRPCAckReceivedEvent > ((event) {
1158
+ _localParticipant? .handleIncomingRpcAck (event.requestId);
1159
+ })
1160
+ ..on < EngineRPCResponseReceivedEvent > ((event) {
1161
+ String ? payload;
1162
+ RpcError ? error;
1163
+
1164
+ if (event.payload.isNotEmpty) {
1165
+ payload = event.response.payload;
1166
+ } else if (event.error != null ) {
1167
+ error = RpcError .fromProto (event.error! );
1168
+ }
1169
+ _localParticipant? .handleIncomingRpcResponse (
1170
+ event.requestId, payload, error);
1171
+ });
1172
+ }
1173
+
1174
+ /// Register a handler for incoming RPC requests.
1175
+ /// @param method, the method name to listen for.
1176
+ /// When a request with this method name is received, the handler will be called.
1177
+ /// The handler should return a string payload to send back to the caller.
1178
+ /// If the handler returns null, an error will be sent back to the caller.
1179
+ void registerRpcMethod (String method, RpcRequestHandler handler) {
1180
+ if (rpcHandlers.containsKey (method)) {
1181
+ throw Exception ('Method $method already registered' );
1182
+ }
1183
+ rpcHandlers[method] = handler;
1184
+ }
1185
+
1186
+ /// Unregister a handler for incoming RPC requests.
1187
+ /// @param method, the method name to unregister.
1188
+ void unregisterRpcMethod (String method) {
1189
+ rpcHandlers.remove (method);
1190
+ }
1191
+ }
0 commit comments