Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

del-wang/echorpc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

30 Commits

Repository files navigation

EchoRPC

NPM Version PyPI Version License

Bidirectional JSON-RPC 2.0 over WebSocket β€” TypeScript & Python.

# TypeScript
npm install echorpc
# Python
pip install echorpc

Features

  • Bidirectional RPC β€” server and client can call each other's methods
  • Pub/Sub β€” fire-and-forget notifications via publish / subscribe
  • Batch requests β€” multiple calls per frame, results returned in order
  • Auth β€” token validated during HTTP upgrade
  • Heartbeat β€” ping/pong with auto-disconnect on timeout
  • Auto-reconnect β€” exponential backoff, handlers and subscriptions preserved
  • Broadcast β€” send to all connections, filter by role, or exclude specific peers

Python

Server

from echorpc import EchoServer
server = EchoServer(port=9100, auth_handler=lambda p: p["token"] == "secret")
# Define a command that clients can call
@server.command("add")
def add(params):
 return {"sum": params["a"] + params["b"]}
# Listen for events from clients
@server.event("chat")
async def on_chat(data):
 print("on_chat", data)
await server.start()

Client

from echorpc import EchoClient
client = EchoClient("ws://localhost:9100", token="secret")
# Let the server call you back
client.register("double", lambda p: p["x"] * 2)
# Subscribe to events
client.subscribe("chat", lambda data: print(data))
await client.connect()
# Call a server command
result = await client.request("add", {"a": 1, "b": 2})
# Publish event to the server
await client.publish("chat", {"text": "hello"})
# Send multiple calls at once
results = await client.batch_request([
 ("add", {"a": 1, "b": 2}),
 ("add", {"a": 3, "b": 4}),
])

TypeScript

Server

import { EchoServer } from "echorpc";
const server = new EchoServer({
 port: 9100,
 authHandler: (p) => p.token === "secret",
});
// Define a command that clients can call
server.register("add", (p: { a: number; b: number }) => ({
 sum: p.a + p.b,
}));
// Listen for events from clients
server.subscribe("chat", async (data) => {
 console.log("chat", data);
});
await server.start();

Client (Node.js)

import WebSocket from "ws";
import { EchoClient } from "echorpc";
const client = new EchoClient("ws://localhost:9100", {
 token: "secret",
 WebSocket,
});
// Let the server call you back
client.register("double", (p) => p.x * 2);
// Subscribe to events
client.subscribe("chat", (data) => console.log(data));
await client.connect();
// Call a server command
const result = await client.request("add", { a: 1, b: 2 });
// Publish event to the server
client.publish("chat", { text: "hello" });
// Send multiple calls at once
const results = await client.batchRequest([
 ["add", { a: 1, b: 2 }],
 ["add", { a: 3, b: 4 }],
]);

Client (Browser)

No WebSocket import needed β€” uses the native one.

import { EchoClient } from "echorpc";
const client = new EchoClient("ws://localhost:9100", { token: "secret" });
await client.connect();

Error Codes

Code Name Meaning
-32700 Parse error Invalid JSON
-32601 Method not found No such method
-32603 Internal error Handler threw
-32001 Not connected No active connection
-32002 Timeout Request timed out
-32003 Auth failed Authentication rejected

License

MIT License Β© 2026-PRESENT Del Wang

About

🐚 Bidirectional JSON-RPC 2.0 over WebSocket β€” TypeScript & Python.

Resources

License

Stars

Watchers

Forks

Packages

Contributors

AltStyle γ«γ‚ˆγ£γ¦ε€‰ζ›γ•γ‚ŒγŸγƒšγƒΌγ‚Έ (->γ‚ͺγƒͺγ‚ΈγƒŠγƒ«) /