Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RPC implementation #1282

Merged
merged 65 commits into from
Oct 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
86c35b7
Move example app into a demo folder
bcherry Oct 8, 2024
3aac217
Move example app into a demo folder
bcherry Oct 8, 2024
63c3e48
rpc example
bcherry Oct 8, 2024
cbbdf45
most of it
bcherry Oct 9, 2024
b47f2f9
all the code
bcherry Oct 9, 2024
18fd5c4
remove excess code
bcherry Oct 9, 2024
2fe91cc
sample
bcherry Oct 9, 2024
23dc6ec
almost working
bcherry Oct 9, 2024
0af85e0
close...
bcherry Oct 9, 2024
dddb7a2
close...
bcherry Oct 9, 2024
6920efa
demo is working
bcherry Oct 9, 2024
af86bbc
exfixes
bcherry Oct 9, 2024
a124ec0
cleanup
bcherry Oct 9, 2024
77be7c8
fmt
bcherry Oct 9, 2024
3e55120
fmt
bcherry Oct 9, 2024
88c402a
Merge remote-tracking branch 'origin/main' into bcherry/rpc
bcherry Oct 9, 2024
fe43c9c
fmt
bcherry Oct 9, 2024
af521a3
README
bcherry Oct 9, 2024
bd62f49
wip
bcherry Oct 9, 2024
6a5fa62
cleanup
bcherry Oct 9, 2024
3da64f4
wip
bcherry Oct 9, 2024
9122f3a
fix tests
bcherry Oct 9, 2024
394c74a
fixes
bcherry Oct 9, 2024
76baf28
fmt
bcherry Oct 9, 2024
c3a450b
disconncect
bcherry Oct 9, 2024
b166135
dots
bcherry Oct 9, 2024
8ed554b
fmt
bcherry Oct 9, 2024
8d00bf0
fix
bcherry Oct 9, 2024
49fc7b6
Create beige-brooms-add.md
bcherry Oct 9, 2024
ab8767e
fix
bcherry Oct 9, 2024
25ec7e5
fixes
bcherry Oct 10, 2024
1b1f768
comments
bcherry Oct 10, 2024
1274704
Merge remote-tracking branch 'origin/bcherry/rpc' into bcherry/rpc
bcherry Oct 10, 2024
53da984
cleanups
bcherry Oct 10, 2024
aeb26d9
clean
bcherry Oct 10, 2024
a0d1326
fixes
bcherry Oct 10, 2024
4e9b5e4
typo
bcherry Oct 10, 2024
e8e24dd
Comment
bcherry Oct 10, 2024
d9dc478
fixes
bcherry Oct 10, 2024
cc0ac40
Fix test
bcherry Oct 10, 2024
390e0e9
ts
bcherry Oct 11, 2024
6cd7f09
fmt
bcherry Oct 11, 2024
c0b4d00
private
bcherry Oct 11, 2024
a0fb12b
better test
bcherry Oct 11, 2024
591ce96
fmt
bcherry Oct 11, 2024
91da706
Merge remote-tracking branch 'origin/main' into bcherry/rpc
bcherry Oct 15, 2024
d30399f
some fixes
bcherry Oct 15, 2024
ffe3c6a
no p on ack
bcherry Oct 15, 2024
900ab2f
fmt
bcherry Oct 15, 2024
2ba2e46
ensure full connection
bcherry Oct 15, 2024
5830010
fmt
bcherry Oct 15, 2024
8b39462
Change to use identities
bcherry Oct 15, 2024
7384beb
fix
bcherry Oct 16, 2024
99005ea
Merge remote-tracking branch 'origin/main' into bcherry/rpc
bcherry Oct 17, 2024
578f550
fmt
bcherry Oct 17, 2024
ab7c453
fix
bcherry Oct 22, 2024
785dcd7
semver
bcherry Oct 22, 2024
fc50b13
fmt
bcherry Oct 22, 2024
7aad151
v
bcherry Oct 22, 2024
fa034af
remove semver package
bcherry Oct 22, 2024
dfbad78
Move data packet into lp
bcherry Oct 22, 2024
b122b38
rpc
bcherry Oct 22, 2024
cfec229
simplify
bcherry Oct 24, 2024
e7f0e17
Merge remote-tracking branch 'origin/main' into bcherry/rpc
bcherry Oct 24, 2024
1ef832c
fmt
bcherry Oct 24, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/beige-brooms-add.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"livekit-client": minor
---

RPC implementation
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -112,3 +112,5 @@ docs/
pkg/
bin/
examples/**/build/

.env.local
54 changes: 54 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -304,12 +304,66 @@ setLogExtension((level: LogLevel, msg: string, context: object) => {
});
```

### RPC

Perform your own predefined method calls from one participant to another.

This feature is especially powerful when used with [Agents](https://docs.livekit.io/agents), for instance to forward LLM function calls to your client application.

#### Registering an RPC method

The participant who implements the method and will receive its calls must first register support:

```typescript
room.localParticipant?.registerRpcMethod(
// method name - can be any string that makes sense for your application
'greet',

// method handler - will be called when the method is invoked by a RemoteParticipant
async (requestId: string, callerIdentity: string, payload: string, responseTimeoutMs: number) => {
console.log(`Received greeting from ${callerIdentity}: ${payload}`);
return `Hello, ${callerIdentity}!`;
}
);
```

In addition to the payload, your handler will also receive `responseTimeoutMs`, which informs you the maximum time available to return a response. If you are unable to respond in time, the call will result in an error on the caller's side.

#### Performing an RPC request

The caller may then initiate an RPC call like so:

```typescript
try {
const response = await room.localParticipant!.performRpc(
'recipient-identity',
'greet',
'Hello from RPC!'
);
console.log('RPC response:', response);
} catch (error) {
console.error('RPC call failed:', error);
}
```

You may find it useful to adjust the `responseTimeoutMs` parameter, which indicates the amount of time you will wait for a response. We recommend keeping this value as low as possible while still satisfying the constraints of your application.

#### Errors

LiveKit is a dynamic realtime environment and calls can fail for various reasons.

You may throw errors of the type `RpcError` with a string `message` in an RPC method handler and they will be received on the caller's side with the message intact. Other errors will not be transmitted and will instead arrive to the caller as `1500` ("Application Error"). Other built-in errors are detailed in `RpcError`.

## Examples

### Demo App

[examples/demo](examples/demo/) contains a demo webapp that uses the SDK. Run it with `pnpm install && pnpm examples:demo`

### RPC Demo

[examples/rpc](examples/rpc/) contains a demo webapp that uses the SDK to showcase the RPC capabilities. Run it with `pnpm install && pnpm dev` from the `examples/rpc` directory.

## Browser Support

| Browser | Desktop OS | Mobile OS |
Expand Down
2 changes: 1 addition & 1 deletion examples/demo/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"extends": "../../tsconfig",
"extends": "../../tsconfig.json",
"compilerOptions": {
"target": "ESNext" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */,
"module": "ESNext" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */,
Expand Down
13 changes: 13 additions & 0 deletions examples/rpc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# RPC Demo

A working multi-participant live demo of the LiveKit RPC feature.

## Running the Demo

1. Create `.env.local` with `LIVEKIT_API_KEY`, `LIVEKIT_API_SECRET`, and `LIVEKIT_URL`
1. Install dependencies: `pnpm install`
2. Start server: `pnpm dev`
3. Open browser to local URL (typically http://localhost:5173)
4. Press the button to watch the demo run

For more detailed information on using RPC with LiveKit, refer to the [main README](../../README.md#rpc).
39 changes: 39 additions & 0 deletions examples/rpc/api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import dotenv from 'dotenv';
import express from 'express';
import type { Express } from 'express';
import { AccessToken } from 'livekit-server-sdk';

dotenv.config({ path: '.env.local' });

const LIVEKIT_API_KEY = process.env.LIVEKIT_API_KEY;
const LIVEKIT_API_SECRET = process.env.LIVEKIT_API_SECRET;
const LIVEKIT_URL = process.env.LIVEKIT_URL;

const app = express();
app.use(express.json());

app.post('/api/get-token', async (req, res) => {
const { identity, roomName } = req.body;

if (!LIVEKIT_API_KEY || !LIVEKIT_API_SECRET) {
res.status(500).json({ error: 'Server misconfigured' });
return;
}

const token = new AccessToken(LIVEKIT_API_KEY, LIVEKIT_API_SECRET, {
identity,
});
token.addGrant({
room: roomName,
roomJoin: true,
canPublish: true,
canSubscribe: true,
});

res.json({
token: await token.toJwt(),
url: LIVEKIT_URL,
});
});

export const handler: Express = app;
19 changes: 19 additions & 0 deletions examples/rpc/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>LiveKit RPC Demo</title>
<link rel="stylesheet" href="./styles.css" />
</head>
<body>
<div class="container">
<h1>LiveKit RPC Demo</h1>
<div id="log-area">
<textarea id="log" rows="15" readonly></textarea>
</div>
<button id="run-demo" class="btn">Run Demo</button>
</div>
<script type="module" src="./rpc-demo.ts"></script>
</body>
</html>
26 changes: 26 additions & 0 deletions examples/rpc/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"name": "livekit-rpc-example",
"version": "1.0.0",
"description": "Example of using LiveKit RPC",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"preview": "vite preview"
},
"dependencies": {
"cors": "^2.8.5",
"dotenv": "^16.4.5",
"express": "^4.21.1",
"livekit-server-sdk": "^2.7.0",
"vite": "^3.2.7",
"vite-plugin-mix": "^0.4.0"
},
"devDependencies": {
"@types/cors": "^2.8.17",
"@types/express": "^5.0.0",
"concurrently": "^8.2.0",
"tsx": "^4.7.0",
"typescript": "^5.4.5"
}
}
Loading
Loading