Hey. So I was trying to register rpc method on fro...
# ask-ai
a
Hey. So I was trying to register rpc method on frontend and call it from backend. I can see the rpc method on the frontend local participation but When I call it from the backend it's saying method is not supported
t
Thanks for reaching out, Synthesize. I'm an AI assistant and I'm here to help. Give me a moment while I research this topic.
Hey there! If you want to register an RPC method on the frontend and call it from the backend in LiveKit, here’s a friendly walkthrough to help you out: 1. Register the RPC method on the frontend (destination participant):
Copy code
room.localParticipant?.registerRpcMethod(
  'greet',
  async (data: RpcInvocationData) => {
    console.log(`Received greeting from ${data.callerIdentity}: ${data.payload}`);
    return `Hello, ${data.callerIdentity}!`;
  }
);
2. Perform the RPC call from the backend (caller participant):
Copy code
try {
  const response = await room.localParticipant!.performRpc({
    destinationIdentity: 'recipient-identity',
    method: 'greet',
    payload: 'Hello from RPC!',
  });
  console.log('RPC response:', response);
} catch (error) {
  console.error('RPC call failed:', error);
}
Just a few things to keep in mind: • Make sure the method name is exactly the same when you register it and when you call it. • Sometimes RPC calls might fail because of timeouts, connection hiccups, or invalid methods — so having good error handling is super helpful. • Your payloads can be strings up to 15KiB, and you’re free to use JSON or whatever format fits your needs. • The default timeout for responses is 10 seconds, but you can tweak that if you need to. If you’re still running into issues, double-check that the method name and destination identity are spot on, and confirm that the frontend participant is properly connected to the room. You’ve got this!
a
useEffect(() => { const p = activeRoom?.localParticipant; if (!p) return; activeRoom.registerRpcMethod("changeChart", async (data) => { console.log("client.changeChart RPC payload:", data.payload); dispatch(setSymbol(data.payload)); return "success"; }); console.log(activeRoom.localParticipant); }, [activeRoom, dispatch]);. async def change_chart(self, context: RunContext[UserData], symbol: str) -> str: room = context.userdata.ctx.room participants = room.remote_participants if not participants: return f"Created a flash card, but no participants found to send it to." participant = next(iter(participants.values()), None) if not participant: return f"Created a flash card, but couldn't get the first participant." logger.info(participant) payload = symbol try: logger.info(participant.identity) await room.local_participant.perform_rpc( destination_identity=participant.identity, method="changeChart", payload=payload, response_timeout=20 ) except Exception as e: logger.exception("RPC failed") return str(e). This is my code. The error is still there
t
Hey there! The "RPC method not supported" error usually pops up when the method you're trying to call hasn’t been properly registered on the other participant's side. No worries though—here are some friendly steps to help you troubleshoot and get things working smoothly: 1. Verify Method Registration: Make sure the destination participant has registered the RPC method using
registerRpcMethod
before any RPC calls happen. For example:
Copy code
activeRoom.localParticipant?.registerRpcMethod(
  "changeChart",
  async (data) => {
    console.log("client.changeChart RPC payload:", data.payload);
    dispatch(setSymbol(data.payload));
    return "success";
  }
);
2. Check Method Name: Double-check that the method name you use in
performRpc
exactly matches the registered method name, including capitalization. 3. Verify Participant Connection: Make sure the destination participant is connected to the room and that the method registration happens after this connection is established. 4. Debugging Tips: • Try logging the list of registered methods on the destination participant to see if your method shows up. • Keep SDK versions consistent across participants to avoid any compatibility hiccups. • Look out for any typos or case mismatches in the method name. If you’re still stuck, it’d be great to double-check: • That the method registration happens after the participant joins the room. • That the destination participant is correctly identified in the
performRpc
call. Hope this helps! Feel free to reach out if you want to chat more about this.
a
My frontend is this, useEffect(() => {     const p = activeRoom?.localParticipant;     if (!p) return;       activeRoom.registerRpcMethod("changeChart", async (data) => {       console.log("client.changeChart RPC payload:", data.payload);       dispatch(setSymbol(data.payload));       return "success";     });     console.log(activeRoom.localParticipant);         }, [activeRoom, dispatch]);.  and my backend is this, async def change_chart(self, context: RunContext[UserData], symbol: str) -> str:         room = context.userdata.ctx.room         participants = room.remote_participants         if not participants:             return f"Created a flash card, but no participants found to send it to."         participant = next(iter(participants.values()), None)         if not participant:             return f"Created a flash card, but couldn't get the first participant."         logger.info(participant)         payload = symbol         try:             logger.info(participant.identity)             await room.local_participant.perform_rpc(                 destination_identity=participant.identity,                 method="changeChart",                 payload=payload,                 response_timeout=20             )         except Exception as e:             logger.exception("RPC failed")             return str(e).
t
Thanks so much for sharing your code! To get to the bottom of this, could you help me confirm a few things? • Is the
activeRoom
object on the frontend fully set up and connected to the room before you call
registerRpcMethod
? • On the backend side, are you sure that the
participant.identity
matches the identity of the frontend participant where the method is registered? • Do you see any errors or logs on the frontend when the backend tries to call the RPC method? Getting these details will really help us figure out what’s going on.
a
Do you see any issue on the code??
t
Thanks for sharing your code! Here are a few things you might want to double-check: Frontend: • Make sure
activeRoom
is fully initialized and connected to the room before you call
registerRpcMethod
. If
activeRoom
is undefined or not connected yet, the method registration won’t work as expected. • Double-check that the method name
"changeChart"
exactly matches (including case) the one used on the backend. • Take a peek at the browser console to see if there are any errors or logs when the backend tries to call the RPC method. Backend: • Ensure that
participant.identity
matches the identity of the frontend participant where the method is registered. If it doesn’t, the RPC call won’t go through. • Verify that
room.local_participant
is properly initialized and connected before you call
perform_rpc
. • Check your logs for any errors or exceptions during the
perform_rpc
call. If you’ve already checked these and the problem is still there, just let me know! We can dig a little deeper together and figure it out.
a
_Room {_events: {…}, _eventsCount: 0, _maxListeners: 100, state: 'connected', activeSpeakers: Array(0), …} abortController : undefined activeSpeakers : [] applyJoinResponse : (joinResponse) => {…} attemptConnection : (url, token, opts, abortController) => {…} audioContext : undefined audioEnabled : true bufferedEvents : [] bufferedSegments : Map(0) {size: 0} byteStreamControllers : Map(0) {size: 0} byteStreamHandlers : Map(0) {size: 0} connOptions : {autoSubscribe: true, maxRetries: 1, peerConnectionTimeout: 15000, websocketTimeout: 15000} connect : (url, token, opts) => {…} connectFuture : undefined connectSignal : (url, token, engine, connectOptions, roomOptions, abortController) => {…} connectionReconcileInterval : 688 disconnect : ƒ () disconnectLock : _ {_locking: Promise, _locks: 0} engine : RTCEngine {_events: {…}, _eventsCount: 0, _maxListeners: undefined, options: {…}, rtcConfig: {…}, …} handleActiveSpeakersUpdate : (speakers) => {…} handleAudioPlaybackFailed : (e2) => {…} handleAudioPlaybackStarted : () => {…} handleChatMessage : (participant, chatMessage) => {…} handleConnectionQualityUpdate : (update) => {…} handleDataPacket : (packet) => {…} handleDeviceChange : () => {…} handleMetrics : (metrics, participant) => {…} handleParticipantUpdates : (participantInfos) => {…} handleRestarting : () => {…} handleRoomUpdate : (room) => {…} handleSignalRestarted : (joinResponse) => {…} handleSipDtmf : (participant, dtmf) => {…} handleSpeakersChanged : (speakerUpdates) => {…} handleStreamStateUpdate : (streamStateUpdate) => {…} handleSubscriptionError : (update) => {…} handleSubscriptionPermissionUpdate : (update) => {…} handleTranscription : (_remoteParticipant, transcription) => {…} handleUserPacket : (participant, userPacket, kind) => {…} handleVideoPlaybackFailed : () => {…} handleVideoPlaybackStarted : () => {…} isE2EEEnabled : false isResuming : false isVideoPlaybackBlocked : false localParticipant : LocalParticipant {_events: {…}, _eventsCount: 0, _maxListeners: 100, audioLevel: 0, isSpeaking: false, …} log : Logger {name: 'livekit-room', levels: {…}, methodFactory: ƒ, getLevel: ƒ, setLevel: ƒ, …} onLocalAttributesChanged : (changedAttributes) => {…} onLocalChatMessageSent : (msg) => {…} onLocalConnectionQualityChanged : (quality) => {…} onLocalParticipantMetadataChanged : (metadata) => {…} onLocalParticipantNameChanged : (name) => {…} onLocalParticipantPermissionsChanged : (prevPermissions) => {…} onLocalTrackMuted : (pub) => {…} onLocalTrackPublished : (pub) => {…} onLocalTrackRestarted : (track) => {…} onLocalTrackUnmuted : (pub) => {…} onLocalTrackUnpublished : (pub) => {…} onMediaDevicesError : (e2, kind) => {…} onPageLeave : () => {…} onTrackProcessorUpdate : (processor) => {…} options : {adaptiveStream: false, dynacast: true, stopLocalTrackOnUnpublish: true, reconnectPolicy: DefaultReconnectPolicy, disconnectOnPageLeave: true, …} regionUrl : undefined regionUrlProvider : RegionUrlProvider {lastUpdateAt: 1754924154383, settingsCacheTime: 3000, attemptedRegions: Array(0), serverUrl: URL, token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiQ…c1NH0.MN0bKwO1h5abXuI96KaEqdwAyR_Q2VmsRtJRYFHH4Sg', …} remoteParticipants : Map(0) {size: 0} roomInfo : type {sid: 'RM_ZWjH6F8kZnU8', name: 'Abid-Y3ncYYA29TSR4nwms5QQwWJGTgn2-Bee-0.6099977185726512', emptyTimeout: 300, departureTimeout: 20, maxParticipants: 0, …} rpcHandlers : Map(1) {'changeChart' => ƒ} serverInfo : type {edition: 1, version: '1.9.0', protocol: 16, region: 'India', nodeId: 'NM_OMUMBAI1B_yAXETbZ8bqHK', …} sidToIdentity : Map(0) {size: 0} startAudio : () => {…} startVideo : () => {…} state : "disconnected" textStreamControllers : Map(0) {size: 0} textStreamHandlers : Map(0) {size: 0} transcriptionReceivedTimes : Map(0) {size: 0} _events : {dataReceived: ƒ} _eventsCount : 1 _maxListeners : 100 canPlaybackAudio : (...) canPlaybackVideo : (...) isRecording : (...) logContext : (...) metadata : (...) name : (...)
This is frontend log
t
Thanks so much for sharing the frontend log! From what I can see, the
rpcHandlers
map does include the
changeChart
method, which means it’s successfully registered on the frontend. That said, the
state
of the room is showing as
"disconnected"
. This might be why the backend isn’t able to call the RPC method. For everything to work smoothly, the room needs to be in a
"connected"
state. Could you please double-check a few things for me? • Make sure the frontend participant is connected to the room when the backend tries to call the RPC method. • Look out for any disconnection events or errors in the frontend logs that might explain why the room is
"disconnected"
. • Verify that the backend is using the correct
destination_identity
that matches the frontend participant’s identity. Feel free to reach out if you’d like me to help further after you’ve checked these points!
a
Status is connected now and agent is speaking but still the rpc method not working
t
Since the room is now connected and the participant is speaking, but the RPC method is still not working, let’s try a few more steps to get this sorted out: 1. Verify RPC Method Registration: • Make sure the method
changeChart
is properly registered on the frontend using
registerRpcMethod
. • Double-check that there aren’t any duplicate registrations or errors during the registration process. 2. Check RPC Invocation: • Confirm the backend is calling
perform_rpc
with the exact method name
changeChart
(remember, it’s case-sensitive). • Verify that the
destination_identity
matches the identity of the frontend participant where the method is registered. 3. Network and Payload: • Make sure there aren’t any network issues or firewalls blocking the RPC traffic. • Check that the payload size stays within the 15KB limit. 4. Error Handling: • Take a look at any errors or exceptions logged on both frontend and backend to help pinpoint what’s going on. • Ensure the RPC handler on the frontend is processing requests within the set
responseTimeout
. If you’re still running into trouble, could you please share: • The exact error message or what you’re seeing happening. • Confirmation that the method names match exactly between registration and invocation. • Any relevant logs or network traces from both frontend and backend.
a
My side on backend and fronted doesn't match is there the issue?
t
Hey! Just a heads-up: if the method names on the backend and frontend don’t match exactly, the RPC call won’t go through. The method name you use in the backend’s
perform_rpc
needs to be the same as the one you registered on the frontend with
registerRpcMethod
. Since method names are case-sensitive, even a tiny difference in capitalization or spelling can cause issues. Could you double-check that the method name
"changeChart"
is exactly the same on both sides? Once that’s sorted, your RPC call should work smoothly. Let me know if you need any help with this!