Skip to content

feat(rtc): add RPC interceptors - #724

Merged
davidzhao merged 2 commits into
mainfrom
dz/rpc-interceptors
Sep 15, 2026
Merged

davidzhao merged 2 commits into
mainfrom
dz/rpc-interceptors

Conversation

@davidzhao

Copy link
Copy Markdown
Member

Port of livekit/python-sdks#806. An RpcInterceptor wraps every RPC the local participant performs (interceptOutgoing) or handles (interceptIncoming), so telemetry can trace calls in both directions without touching user code. Interceptors run in registration order, the first outermost; errors from the remote side or from the handler flow through the chain unchanged, and a call for an unregistered method reaches the chain with next throwing UNSUPPORTED_METHOD, so an interceptor can record that the agent never registered it.

RpcInvocationData now carries the invoked method, and RpcCallInfo mirrors performRpc's parameters so an interceptor can hand a modified call to next.

Deliberate deviation from the Python SDK: the Node SDK never enforced the caller's responseTimeout on the handler locally (the caller times out on its side), and promises cannot be cancelled, so the incoming chain is not raced against a deadline here.

Port of livekit/python-sdks#806. An RpcInterceptor wraps every RPC the
local participant performs (interceptOutgoing) or handles
(interceptIncoming), so telemetry can trace calls in both directions
without touching user code. Interceptors run in registration order, the
first outermost; errors from the remote side or from the handler flow
through the chain unchanged, and a call for an unregistered method
reaches the chain with `next` throwing UNSUPPORTED_METHOD, so an
interceptor can record that the agent never registered it.

RpcInvocationData now carries the invoked `method`, and RpcCallInfo
mirrors performRpc's parameters so an interceptor can hand a modified
call to `next`.

Deliberate deviation from the Python SDK: the Node SDK never enforced
the caller's responseTimeout on the handler locally (the caller times
out on its side), and promises cannot be cancelled, so the incoming
chain is not raced against a deadline here.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@davidzhao
davidzhao requested review from a team, 1egoman and lukasIO September 15, 2026 05:07
@changeset-bot

changeset-bot Bot commented Sep 15, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 43cfa5d

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@livekit/rtc-node Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Devin Review

The FFI layer answers UNSUPPORTED_METHOD for a method nobody registered
before the SDK's handler runs, so the callee's incoming interceptor never
sees such a call in a real room. The e2e assertion expected it to; the
Python equivalent only held in unit tests with fake continuations.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

@1egoman 1egoman left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally makes sense to me, cool feature!

Comment on lines +124 to +126
#### Intercepting RPC calls

An `RpcInterceptor` wraps every RPC the local participant performs or handles, which is useful for logging, tracing, or attaching metadata to payloads. Each method receives the call and a `next` continuation; return what `next` returns. Interceptors run in the order they were added, the first being outermost, and errors from the remote side or from your handler flow through them unchanged. Implement only the direction you care about.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick, but probably too late to change: In other "web framework" contexts usually this is called middleware. I wonder if that maybe would have been a better name for this?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

they are similar but I think there are slight differences. see: https://stackoverflow.com/questions/54863655/whats-the-difference-between-interceptor-vs-middleware-vs-filter-in-nest-js

ours is higher level with less power.. IMO interceptor is right

@davidzhao
davidzhao merged commit 19a1187 into main Sep 15, 2026
10 checks passed
@davidzhao
davidzhao deleted the dz/rpc-interceptors branch September 15, 2026 16:41
@github-actions github-actions Bot mentioned this pull request Sep 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants