Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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: idpeer_addrlocal_addr
  • channel():cloneable external channel
  • stats():启用 stats 时返回 ConnectionStats
  • writeflushwrite_and_flush
  • close

DatagramHandler

DatagramHandler<I> 是 UDP inbound side 的终点。它使用 DatagramContext<W>,支持 writewrite_toflushwrite_and_flushwrite_to_and_flushclose

#![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 更清晰。