文章目录
-
- 一、关于项目
- 二、安装配置
- 三、使用示例
- 四、技术细节
- 五、部署方案
-
- [1、Cloudflare Workers](#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管道
支持在单次网络往返中完成调用链
-
能力安全模型
提供基于能力的安全模式
二、安装配置
bash
npm i capnweb
三、使用示例
1、基础示例
客户端代码:
js
import { newWebSocketRpcSession } from "capnweb";
let api = newWebSocketRpcSession("wss://example.com/api");
let result = await api.hello("World");
console.log(result);
服务端代码:
js
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示例
共享类型定义:
ts
interface PublicApi {
authenticate(apiToken: string): AuthedApi;
getUserProfile(userId: string): Promise<UserProfile>;
}
服务端实现:
ts
class ApiServer extends RpcTarget implements PublicApi {
// 实现接口方法
}
客户端批处理调用:
ts
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
ts
export default {
fetch(request, env, ctx) {
return newWorkersRpcResponse(request, new MyApiImpl());
}
}
2、Node.js服务
ts
http.createServer(async (request, response) => {
await nodeHttpBatchRpcResponse(request, response, new MyApiImpl());
});
3、WebWorker通信
ts
let channel = new MessageChannel()
newMessagePortRpcSession(channel.port1, new Greeter());
let stub = newMessagePortRpcSession<Greeter>(channel.port2);
六、安全建议
- 避免使用Cookie认证(推荐内建RPC认证)
- 实现操作频率限制
- 考虑运行时类型检查(如使用Zod)
伊织 xAI 2025-09-25