Cap‘n Web - JavaScript原生RPC系统
文章目录
- 一、关于项目
- 1、项目概览
- 2、相关链接资源
- 3、核心特性
- 二、安装配置
- 三、使用示例
- 1、基础示例
- 2、高级TypeScript示例
- 四、技术细节
- 1、值类型传递
- 2、RpcTarget机制
- 3、资源管理
- 五、部署方案
- 1、Cloudflare Workers
- 2、Node.js服务
- 3、WebWorker通信
- 六、安全建议
一、关于项目
1、项目概览
Cap’n Web是与Cap’n Proto(由同一作者创建)理念相近的RPC系统,专为Web技术栈设计。主要特点:
- 采用对象能力协议("Cap’n"是"capabilities and"的缩写)
- 无模式定义,几乎零样板代码
- 完美支持TypeScript
- 底层序列化采用人类可读的JSON格式
- 开箱支持HTTP、WebSocket和postMessage()传输
- 兼容所有主流浏览器、Cloudflare Workers、Node.js等现代JavaScript运行时
- 压缩后体积小于10kB且无依赖
2、相关链接资源
- Github:https://github.com/cloudflare/capnweb
- 官方文档:https://capnproto.org
- 作者:Cloudflare团队
- npm包:https://www.npmjs.com/package/capnweb
- 技术博客:https://blog.cloudflare.com/javascript-native-rpc/
3、核心特性
-
双向调用
支持客户端调用服务端,服务端也可回调客户端 -
函数引用传递
通过RPC传递函数时会生成"存根",调用存根将触发RPC回调 -
对象引用传递
继承RpcTarget
的类实例会按引用传递 -
Promise管道
支持在单次网络往返中完成调用链 -
能力安全模型
提供基于能力的安全模式
二、安装配置
npm i capnweb
三、使用示例
1、基础示例
客户端代码:
import { newWebSocketRpcSession } from "capnweb";
let api = newWebSocketRpcSession("wss://example.com/api");
let result = await api.hello("World");
console.log(result);
服务端代码:
import { RpcTarget, newWorkersRpcResponse } from "capnweb";class MyApiServer extends RpcTarget {hello(name) {return `Hello, ${name}!`}
}export default {fetch(request, env, ctx) {let url = new URL(request.url);if (url.pathname === "/api") {return newWorkersRpcResponse(request, new MyApiServer());}return new Response("Not found", {status: 404});}
}
2、高级TypeScript示例
共享类型定义:
interface PublicApi {authenticate(apiToken: string): AuthedApi;getUserProfile(userId: string): Promise<UserProfile>;
}
服务端实现:
class ApiServer extends RpcTarget implements PublicApi {// 实现接口方法
}
客户端批处理调用:
let api = newHttpBatchRpcSession<PublicApi>("https://example.com/api");
let authedApi = api.authenticate(apiToken);
let userIdPromise = authedApi.getUserId();
let profilePromise = api.getUserProfile(userIdPromise);
let [profile] = await Promise.all([profilePromise]);
四、技术细节
1、值类型传递
支持传递的类型包括:
- 基本类型:字符串、数字、布尔值等
- 普通对象和数组
bigint
和Date
Uint8Array
和Error
2、RpcTarget机制
继承RpcTarget
的类实例会按引用传递,注意:
- 仅暴露原型方法(非实例属性)
- TypeScript的
private
修饰符不影响RPC可见性 - 使用
#
前缀可实现真正私有方法
3、资源管理
推荐策略:
- 显式释放存根(通过
Symbol.dispose
) - 使用短生命周期会话
五、部署方案
1、Cloudflare Workers
export default {fetch(request, env, ctx) {return newWorkersRpcResponse(request, new MyApiImpl());}
}
2、Node.js服务
http.createServer(async (request, response) => {await nodeHttpBatchRpcResponse(request, response, new MyApiImpl());
});
3、WebWorker通信
let channel = new MessageChannel()
newMessagePortRpcSession(channel.port1, new Greeter());
let stub = newMessagePortRpcSession<Greeter>(channel.port2);
六、安全建议
- 避免使用Cookie认证(推荐内建RPC认证)
- 实现操作频率限制
- 考虑运行时类型检查(如使用Zod)
伊织 xAI 2025-09-25