Cap‘n Web - JavaScript原生RPC系统

文章目录


一、关于项目

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、相关链接资源


3、核心特性

  1. 双向调用

    支持客户端调用服务端,服务端也可回调客户端

  2. 函数引用传递

    通过RPC传递函数时会生成"存根",调用存根将触发RPC回调

  3. 对象引用传递

    继承RpcTarget的类实例会按引用传递

  4. Promise管道

    支持在单次网络往返中完成调用链

  5. 能力安全模型

    提供基于能力的安全模式


二、安装配置

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、值类型传递

支持传递的类型包括:

  • 基本类型:字符串、数字、布尔值等
  • 普通对象和数组
  • bigintDate
  • Uint8ArrayError

2、RpcTarget机制

继承RpcTarget的类实例会按引用传递,注意:

  • 仅暴露原型方法(非实例属性)
  • TypeScript的private修饰符不影响RPC可见性
  • 使用#前缀可实现真正私有方法

3、资源管理

推荐策略:

  1. 显式释放存根(通过Symbol.dispose
  2. 使用短生命周期会话

五、部署方案

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

相关推荐
大布布将军8 分钟前
⚡️ 性能加速器:利用 Redis 实现接口高性能缓存
前端·数据库·经验分享·redis·程序人生·缓存·node.js
Change!!11 分钟前
uniapp写的h5,怎么根据页面详情,设置不同的标题
前端·uni-app·标题
浅箬12 分钟前
uniapp 打包之后出现shadow-grey.png去除
前端·uni-app
梵得儿SHI16 分钟前
(第五篇)Spring AI 核心技术攻坚:流式响应与前端集成实现【打字机】效果
前端·webflux·springai·流式响应技术·低延迟ai交互·reactive编程原理·streamapi设计
鹏多多18 分钟前
一文搞懂柯里化:函数式编程技巧的解析和实践案例
前端·javascript·vue.js
前端码农一枚26 分钟前
前端打包性能优化全攻略
前端
Roc.Chang27 分钟前
终极指南:解决 Vue 项目中 “regenerator-runtime/runtime“ 缺失报错
前端·javascript·vue.js·webpack·前端工程
AAA阿giao28 分钟前
从树到楼梯:数据结构与算法的奇妙旅程
前端·javascript·数据结构·学习·算法·力扣·
BD_Marathon31 分钟前
Vue3组件(SFC)拼接页面
前端·javascript·vue.js
wregjru32 分钟前
【C++】2.3 二叉搜索树的实现(附代码)
开发语言·前端·javascript