# Realtime Gateway + Cloudflare Tunnel 本机联调说明 本文档说明如何在**不正式部署到线上服务器**的前提下,把本机的 `realtime-gateway` 暴露给外部设备或远程联调方。 适用场景: - 真机调试 - 外网联调 - 家长端 / 场控端远程验证 - 演示环境 不适用场景: - 正式生产实时链路 - 严格 SLA 场景 - 高稳定长时间压测 --- ## 1. 推荐结论 当前阶段建议: 1. 网关继续运行在本机 2. 本机使用 Cloudflare Tunnel 暴露新网关 3. 旧模拟器继续本地运行 4. 旧模拟器通过桥接把数据发给本机新网关 5. 外部客户端只访问 Cloudflare Tunnel 暴露出来的 `wss` 地址 这样做的好处: - 不需要先买独立服务器 - 不需要先做正式公网部署 - 不改变当前本机开发结构 - 新旧链路可以并行使用 --- ## 2. 本机网关配置 推荐先使用: [tunnel-dev.json](D:/dev/cmr-mini/realtime-gateway/config/tunnel-dev.json) 这个配置相比开发默认配置更适合 Tunnel 联调: - 端口改为 `18080` - 关闭匿名 consumer - token 不再使用默认开发值 建议先把其中的 token 改成你自己的值。 启动方式: ```powershell cd D:\dev\cmr-mini\realtime-gateway go build -o .\bin\gateway.exe .\cmd\gateway .\bin\gateway.exe -config .\config\tunnel-dev.json ``` 本机地址: - HTTP: `http://127.0.0.1:18080` - WebSocket: `ws://127.0.0.1:18080/ws` --- ## 3. Quick Tunnel 方案 Quick Tunnel 最适合当前阶段。 Cloudflare 官方文档说明: - Quick Tunnel 用于测试和开发,不建议生产使用 - 可以直接把本地 `http://localhost:8080` 之类的地址暴露出去 - 命令形式是 `cloudflared tunnel --url http://localhost:8080` 来源: - [Quick Tunnels](https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/do-more-with-tunnels/trycloudflare/) - [Set up Cloudflare Tunnel](https://developers.cloudflare.com/tunnel/setup/) ### 3.1 启动 Quick Tunnel 你的网关如果跑在 `18080`: ```powershell cloudflared tunnel --url http://localhost:18080 ``` 启动后,`cloudflared` 会输出一个随机 `trycloudflare.com` 域名。 例如: ```text https://random-name.trycloudflare.com ``` 对应的 WebSocket 地址就是: ```text wss://random-name.trycloudflare.com/ws ``` 注意: - 对外使用时,WebSocket 必须写成 `wss://` - 本地 origin 仍然是 `http://localhost:18080` ### 3.2 Quick Tunnel 限制 Cloudflare 官方说明里,Quick Tunnel 当前有这些限制: - 仅适合测试和开发 - 有并发请求上限 - 不支持 SSE 因此它适合: - 临时分享联调地址 - 验证 WebSocket 接入 - 短期演示 不适合拿来当正式生产入口。 另外,官方文档提到: - 如果本机 `.cloudflared` 目录里已有 `config.yaml`,Quick Tunnel 可能不能直接使用 来源: - [Quick Tunnels](https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/do-more-with-tunnels/trycloudflare/) --- ## 4. Named Tunnel 方案 如果你后面不想每次拿随机域名,可以改用 Named Tunnel。 这时推荐的本地 `cloudflared` 配置示例在: [config.example.yml](D:/dev/cmr-mini/realtime-gateway/deploy/cloudflared/config.example.yml) 示例内容: ```yaml tunnel: YOUR_TUNNEL_ID credentials-file: C:\Users\YOUR_USER\.cloudflared\YOUR_TUNNEL_ID.json ingress: - hostname: gateway-dev.example.com service: http://localhost:18080 - service: http_status:404 ``` 关键点: - Tunnel 把 `gateway-dev.example.com` 映射到本机 `http://localhost:18080` - 最后一条 `http_status:404` 是 catch-all Cloudflare 官方文档对 published application 和 ingress 的说明见: - [Set up Cloudflare Tunnel](https://developers.cloudflare.com/tunnel/setup/) - [Protocols for published applications](https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/routing-to-tunnel/protocols/) 启动后,对外 WebSocket 地址就是: ```text wss://gateway-dev.example.com/ws ``` --- ## 4.1 外部 consumer 小工具 如果你要在另一台机器上用仓库里的 `mock-consumer` 做联调,推荐复制: [consumer-tunnel.example.json](D:/dev/cmr-mini/realtime-gateway/config/consumer-tunnel.example.json) [consumer-gps-heart.example.json](D:/dev/cmr-mini/realtime-gateway/config/consumer-gps-heart.example.json) 填好实际的公网地址和 token,例如: ```json { "url": "wss://gateway-dev.example.com/ws", "token": "your-consumer-token", "deviceId": "child-001", "topics": [ "telemetry.location", "telemetry.heart_rate" ], "snapshot": true } ``` 然后运行: ```powershell cd D:\dev\cmr-mini\realtime-gateway go run .\cmd\mock-consumer -config .\config\consumer-tunnel.example.json ``` 命令行参数会覆盖配置文件中的同名项,所以临时换 `deviceId` 时可以直接追加: ```powershell go run .\cmd\mock-consumer -config .\config\consumer-tunnel.example.json -device-id child-002 ``` 如果只想临时直接从命令行看 GPS 和心率: ```powershell go run .\cmd\mock-consumer -url wss://gateway-dev.example.com/ws -token your-consumer-token -device-id child-001 -topics telemetry.location,telemetry.heart_rate ``` --- ## 5. 旧模拟器如何配合 旧模拟器仍然本地运行: ```powershell cd D:\dev\cmr-mini npm run mock-gps-sim ``` 然后在旧模拟器页面的“新网关桥接”区域里填: - 网关地址:`ws://127.0.0.1:18080/ws` - Producer Token:与你 `tunnel-dev.json` 里配置一致 - 目标 Device ID:按你的联调对象填写 - Source ID:例如 `mock-gps-sim-a` 这里要注意: - 旧模拟器桥接到的是**本机网关地址** - 外部消费者连接的是**Cloudflare Tunnel 暴露的公网地址** 不要把旧模拟器桥接目标直接写成公网 `wss` 地址。 旧模拟器和网关都在本机,直接走本地回环最稳。 --- ## 6. 推荐联调拓扑 ```text 旧模拟器页面 -> 本机 mock-gps-sim -> 本机 realtime-gateway (ws://127.0.0.1:18080/ws) -> Cloudflare Tunnel -> 外部 consumer / 真机 / 调试端 (wss:///ws) ``` 这样职责最清晰: - 旧模拟器只负责发模拟数据 - 新网关负责实时中转 - Cloudflare Tunnel 只负责把本机网关暴露到外部 --- ## 7. 当前阶段的安全建议 即使只是联调,也建议至少做到: - `allowAnonymousConsumers = false` - Producer / Consumer / Controller token 全部替换 - 不把默认 token 长期暴露在公网链接中 - Tunnel 只暴露新网关,不一定要暴露旧模拟器 UI 如果只是你自己本机调试: - 旧模拟器 UI 保持本地访问即可 - 只把 `realtime-gateway` 暴露出去 --- ## 8. 结论 当前阶段最推荐的方案是: 1. 本机用 [tunnel-dev.json](D:/dev/cmr-mini/realtime-gateway/config/tunnel-dev.json) 启动新网关 2. 本机旧模拟器桥接到 `ws://127.0.0.1:18080/ws` 3. 用 `cloudflared tunnel --url http://localhost:18080` 先跑 Quick Tunnel 4. 外部客户端使用 `wss:///ws` 5. 等你需要固定域名或更稳定的入口时,再切换 Named Tunnel 这条路径最轻、最稳,也最符合你现在“先不正式上线”的目标。