Handlers
rs-netty 有五类 stage trait。它们都在 src/traits.rs,并通过 trait-variant 生成 Send 版本作为公开主接口。
Inbound
Inbound<I> 用于解码后、final handler 前的入站转换:
#![allow(unused)]
fn main() {
struct Trim;
impl Inbound<String> for Trim {
type Out = String;
async fn read(
&mut self,
_ctx: &mut rs_netty::InboundContext,
msg: String,
) -> rs_netty::Result<rs_netty::Flow<Self::Out>> {
Ok(rs_netty::Flow::Next(msg.trim().to_string()))
}
}
}
InboundContext 暴露 id()、peer_addr()、local_addr(),不提供写能力。
Business
Business<I> 是 inbound 和 final handler 之间的应用级转换阶段。它和 Inbound 的类型形状类似,但方法名是 handle,context 是 BusinessContext。builder 限制是:进入 business 后只能继续加 business 或 final handler,不能再回到 inbound。
Handler
Handler<I> 是 TCP inbound side 的终点:
#![allow(unused)]
fn main() {
impl Handler<Request> for Router {
type Write = Response;
async fn read(&mut self, ctx: &mut Context<Self::Write>, req: Request) -> Result<()> {
ctx.write_and_flush(Response { body: req.body }).await
}
}
}
type Write 是 handler 能写回 outbound side 的应用类型。后续 outbound stage 会从这个类型开始转换,最终转成 codec 可编码的类型。
Context<W> 提供:
- identity:
id、peer_addr、local_addr channel():cloneable external channelstats():启用 stats 时返回ConnectionStatswrite、flush、write_and_flushclose
DatagramHandler
DatagramHandler<I> 是 UDP inbound side 的终点。它使用 DatagramContext<W>,支持 write、write_to、flush、write_and_flush、write_to_and_flush 和 close。
#![allow(unused)]
fn main() {
impl DatagramHandler<String> for UdpEcho {
type Write = String;
async fn read(&mut self, ctx: &mut DatagramContext<Self::Write>, msg: String) -> Result<()> {
ctx.write_and_flush(format!("echo: {msg}")).await
}
}
}
Outbound
Outbound<I> 用于把 handler 写出的应用类型渲染成下游 outbound 类型。最终 outbound 类型必须由 codec encode。
#![allow(unused)]
fn main() {
struct RenderResponse;
impl Outbound<Response> for RenderResponse {
type Out = String;
async fn write(
&mut self,
_ctx: &mut rs_netty::OutboundContext,
msg: Response,
) -> rs_netty::Result<rs_netty::Flow<Self::Out>> {
Ok(rs_netty::Flow::Next(msg.body))
}
}
}
OutboundContext 同样只暴露 identity,不提供直接写能力。
Macro Or Manual Impl
#[handler] 适合一进一出的简单 final handler,或者 consume-only handler。需要直接访问 Context / DatagramContext、控制 flush timing、多次写入、关闭连接或拿 channel() 时,写手动 impl 更清晰。