Cloudflare Workers 的网络边界正在发生变化:通过新的 connect(socket) 处理器,并经由 Spectrum 路由,Workers 可以接收入站 TCP 连接。这个变化结束了持续八年的“只能处理 HTTP”限制,也让容器能够运行全双工 gRPC 服务。
目前这些能力都处于私有测试阶段,因此生产环境还不能直接依赖具体 API 细节。不过,从架构上看,Cloudflare 正在把 Workers 和容器从传统的 HTTP 边缘函数,扩展成能够承载长连接、二进制协议和内部服务通信的运行时。
从 HTTP 请求到入站 TCP
过去,Workers 的典型模型是:客户端发起 HTTP 请求,Worker 返回 HTTP 响应。应用只能在这个请求生命周期内工作,无法像普通 TCP 服务那样主动接受连接并持续读写字节流。
新的 connect(socket) 处理器改变了这一点。连接可以通过 Spectrum 到达 Cloudflare 的边缘网络,再交给 Worker 或相关运行时处理。对于需要自定义 TCP 协议、长连接或双向通信的服务,这比把所有流量包装成 HTTP 更自然。
这并不意味着所有现有 Worker 都会自动获得 TCP 监听能力。私有测试阶段通常还涉及账号资格、Spectrum 配置、端口映射、协议限制和运行时版本。部署前应确认以下边界:
- 入站 TCP 端口如何申请和路由。
- 连接空闲超时、并发数和单连接生命周期限制。
- TLS 终止发生在 Spectrum、Worker 还是应用容器。
- Worker 是否支持任意二进制读写,还是只支持特定协议。
- 监控、日志和连接级别的故障排查能力是否已经可用。
gRPC:容器获得全双工,Worker 通过 gRPC-Web 接入
这次发布中,gRPC 是第一个明确建立在入站 TCP 能力之上的协议方向。
容器可以运行完整的 gRPC 服务,包括双向流式调用。客户端和服务端都可以持续发送消息,这适合实时协作、设备控制、事件订阅和内部服务通信等场景。
Workers 的能力有所不同:它们支持 unary RPC 和 server-streaming RPC,并通过自动的 gRPC-Web 转换与浏览器或 HTTP 客户端连接。这种分工比较实际:
- 需要完整双向 gRPC 的服务,可以部署到容器中。
- 需要在边缘执行认证、路由、缓存或轻量业务逻辑的入口,可以使用 Worker。
- 浏览器端不需要直接实现原生 HTTP/2 gRPC,可以通过 gRPC-Web 访问后端。
需要注意,gRPC-Web 并不等同于完整的双向 gRPC。客户端流式和双向流式能力是否可用,应以具体运行时和私有测试文档为准,不能仅凭“支持 gRPC”这一描述推断。
一个可改造的最小服务拓扑
下面是一个概念性拓扑示例。它不是私有测试 API 的正式配置文件,而是帮助团队拆分职责的最小模型:
Browser or HTTP client
|
| gRPC-Web / HTTPS
v
Cloudflare Worker
- authentication
- request routing
- unary RPC
- server streaming
|
| internal gRPC
v
Container service
- full-duplex gRPC
- long-lived connections
- application protocol
可以这样实践:把 Worker 作为公网入口和策略层,把需要长时间保持连接或处理双向流的部分放入容器。这样既能让边缘层承担鉴权和流量治理,也不会强行把复杂的双向协议塞进 Worker 的请求处理模型。
示例:定义一个 gRPC-Web 入口
下面的代码展示一种可改造的 Worker 侧伪实现。由于该能力处于私有测试阶段,实际 SDK 名称、绑定方式和 connect(socket) 签名需要以 Cloudflare 提供的测试文档为准。示例中的业务函数是普通 JavaScript,可以先用来设计接口边界。
// worker.js
// 假设:私有测试运行时提供 connect(socket) 事件入口。
export default {
async fetch(request, env) {
const url = new URL(request.url);
if (url.pathname === "/healthz") {
return new Response("ok", { status: 200 });
}
if (url.pathname === "/grpc/OrderService/GetOrder") {
if (request.headers.get("authorization") !== `Bearer ${env.API_TOKEN}`) {
return new Response("unauthorized", { status: 401 });
}
const input = await request.arrayBuffer();
const output = await callContainerGrpc(env.ORDER_SERVICE, input);
return new Response(output, {
headers: {
"content-type": "application/grpc-web+proto"
}
});
}
return new Response("not found", { status: 404 });
},
async connect(socket, env) {
// 仅作协议边界示例:实际 connect API 以私有测试版本为准。
const reader = socket.readable.getReader();
const writer = socket.writable.getWriter();
try {
while (true) {
const { value, done } = await reader.read();
if (done) break;
// 在这里解析自定义 TCP 帧,或转发到容器服务。
await writer.write(value);
}
} finally {
reader.releaseLock();
writer.releaseLock();
socket.close();
}
}
};
async function callContainerGrpc(service, payload) {
// 假设 service 是指向容器 gRPC 服务的内部连接绑定。
// 真实项目中应使用平台提供的 gRPC 客户端或连接 API。
return service.request(payload);
}
运行前需要替换 API_TOKEN、ORDER_SERVICE 以及容器连接方式。示例重点不在于复制某个尚未公开的 SDK,而在于明确两条路径:HTTP/gRPC-Web 请求适合在 Worker 中处理,原始 TCP 或全双工 gRPC 则交给支持长连接的运行时。
这项能力适合什么场景
它更适合以下类型的服务:
- 需要边缘接入但不是纯 HTTP 的设备协议。
- 需要持续连接的内部 RPC 或事件通道。
- 将公网鉴权、限流和路由放在边缘,核心双向流放在容器。
- 逐步把现有 TCP 服务接入 Cloudflare 网络,而不立即改写成 HTTP。
不适合直接迁移的场景也很明确。低延迟交易、严格控制连接生命周期的协议、依赖固定源地址的旧系统,以及需要完整客户端流式能力的 gRPC 应用,都应先验证网络路径和运行时限制。边缘网络减少了接入距离,但不会自动消除后端容量、协议兼容性和状态管理问题。
落地前检查清单
私有测试开放后,可以按下面顺序验证:
- 用最小 TCP echo 服务确认入站连接、端口路由和关闭行为。
- 用 unary gRPC 验证序列化、鉴权、错误码和超时。
- 用 server streaming 检查长响应期间的连接稳定性。
- 在容器中验证全双工 gRPC 的背压、重连和优雅关闭。
- 为连接数、活跃连接时长、消息大小和错误类型建立监控。
- 明确哪些逻辑运行在 Worker,哪些逻辑必须保留在容器。
Cloudflare Workers 接收入站 TCP 的意义,不只是多了一个处理器。它把边缘运行时从 HTTP 请求入口推向更通用的网络服务入口,而 gRPC 正好提供了一个检验协议兼容性、流式处理和容器协作方式的起点。由于当前仍是私有测试,最稳妥的采用策略是先做小规模协议验证,再决定是否迁移真实长连接业务。