troupe-gateway
troupe-gateway
Troupe 的外部端点传输桥:把"外部客户端 ↔ actor"的通用传输管理收编成开箱即用的伴生 shard,协议路由留给应用。分层边界与决策记录见 troupe-planning ADR-0007。
职责边界(ADR-0007 L3)
负责:WS 会话生命周期、出站有界 mailbox + 限时投递 + 溢出策略(Drop/Disconnect)、Outbox 派发循环、event_id 去重、握手信息暴露。
不负责:应用协议路由、业务语义(房间/昵称)、认证授权、路由/中间件/序列化(那是 kemal/athena 的领域)。
快速开始
require "troupe-gateway"
stage = Troupe::Stage.new
stage.register(RoomActor.troupe_manifest) # 你的 actor
gateway = Troupe::Gateway::WebSocket.new(stage.store)
# 应用协议路由:上行消息 → actor 调用
gateway.on_message = ->(session : Troupe::Gateway::Session, raw : String) do
# 解析 raw → typed agent 调用 → gateway.deliver(session, 回复)
end
# Outbox 事件路由(已按 event_id 去重;至少一次由 troupe 保证)
gateway.on_outbox = ->(record : Troupe::OutboxRecord) do
# 按业务把 record.payload 投给相关会话:gateway.deliver_id / broadcast
end
gateway.track(Troupe::ActorId.new("chat", "room", "lobby")) # 参与派发轮询
port = gateway.listen("127.0.0.1", 7777)
API
| 成员 | 说明 |
|---|---|
WebSocket.new(store, config = Config.new) |
store 用于 Outbox 派发 |
on_message(Session, String) |
上行原文回调 |
on_connect(Session) : Bool |
接纳钩子,false 拒绝(不触发 on_disconnect) |
on_disconnect(Session) |
断线清理回调 |
on_outbox(OutboxRecord) |
Outbox 事件回调(去重后) |
track / untrack(ActorId) |
派发循环的轮询对象 |
deliver(session, payload) : Bool |
限时投递;溢出按策略 |
deliver_id(id, payload) : Bool |
按会话 id 投递 |
broadcast(payload, except id = nil) : Int32 |
全体广播(可排除),返回成功数 |
duplicate?(event_id) : Bool |
事件去重查询 |
listen(host, port) : Int32 / stop |
启停(listen 返回实际端口) |
Session |
id / meta / path / headers / send 前的投递句柄 |
Config:mailbox_cap(默认 256)、push_wait(200ms)、overflow(Drop/Disconnect)、dedup(true)、dedup_cache(4096)、dispatch_interval(50ms)、service_name。
验证
crystal spec # 路由/握手/广播/溢出/去重/断线/Outbox 派发
crystal run examples/chat_echo.cr
License
MIT,见 LICENSE。
Repository
troupe-gateway
Owner
Statistic
- 0
- 0
- 0
- 0
- 1
- about 3 hours ago
- November 15, 2026
License
MIT License
Links
Synced at
Sun, 15 Nov 2026 15:54:44 GMT
Languages