Solon v4.1.0

Solon Rpc 通讯通道和序列化组件

</> markdown
2026年9月11日 下午5:37:43

一次 Nami 调用至少要解决两件事:通过什么传输,以及如何把 Java 数据变成字节

接口代理 → Channel → 请求字节/HTTP body → 服务端 Server
         ↘ Encoder/Decoder ↗       ↘ Serialization

1、通道组件

通道客户端组件对口的服务端支持组件
Http 通道nami-channel-httpsolon-server-jdkhttp
solon-server-smarthttp
solon-server-jetty
solon-server-undertow
Socket.D 通道nami-channel-socketd + socket.dsolon-server-socketd + socket.d

2、序列化方案组件

序列化方案客户端组件对口的服务端组件
Form 方案表单模式
Json 方案nami-coder-snack3
nami-coder-snack4
nami-coder-fastjson
nami-coder-fastjson2
nami-coder-jackson
solon-serialization-snack3
solon-serialization-snack4
solon-serialization-fastjson
solon-serialization-fastjson2
solon-serialization-jackson
Hessian 方案nami-coder-hessiansolon-serialization-hessian
Fury 方案nami-coder-furysolon-serialization-fury
Kryo 方案nami-coder-kryosolon-serialization-kryo
Protostuff 方案nami-coder-protostuffsolon-serialization-protostuff
Abc 方案nami-coder-abcsolon-serialization-abc

选择序列化方案时,尽量客户端与服务端的框架一一对应。

3、 常见的配对组合

类型客户端服务端
HTTP + JSONnami-channel-http +
nami-coder-snack4
HTTP server +
solon-serialization-snack4
HTTP + Jacksonnami-channel-http +
nami-coder-jackson
HTTP server +
solon-serialization-jackson
Socket.Dnami-channel-socketdsolon-server-socketd
Hessiannami-coder-hessiansolon-serialization-hessian
Fury/Kryo/Protostuff对应 nami-coder-*对应 solon-serialization-*

客户端和服务端应选择同一种 wire format。只更换客户端 coder,通常会得到解码失败,而不是“自动兼容”。

4、 为什么示例要写 JSON Header

@NamiClient(
    url = "http://localhost:9001/rpc/v1/user",
    headers = ContentTypes.JSON)
UserService userService;

ContentTypes.JSON 会声明请求和接收内容类型。Nami 初始化配置时会根据 Accept 选择 decoder;HTTP channel 发送带 body 的请求时会根据 Content-Type 选择 encoder。显式声明后更容易确认实际协议。

5、 Builder 中显式指定组件

脱离 Solon 注入时,可以明确指定:

UserService service = Nami.builder()
    .url("http://localhost:9001/rpc/v1/user")
    .encoder(Snack4Encoder.instance)
    .decoder(Snack4Decoder.instance)
    .channel(HttpChannel.instance)
    .create(UserService.class);

需要导入:

import org.noear.nami.channel.http.HttpChannel;
import org.noear.nami.coder.snack4.Snack4Decoder;
import org.noear.nami.coder.snack4.Snack4Encoder;

实际项目也可以只配置 URL 和注解头,让插件自动按 scheme/content type 查找组件。显式配置适合独立 Java 程序、排查“组件是否注册”问题。

6、 HTTP 参数是怎样发送的

根据当前 HttpChannel 源码:

  • GET 请求的普通参数会拼到 query string。
  • @NamiBody 的参数会作为 body,其他参数仍可进入 query。
  • Content-Type 为表单类型时走表单提交。
  • 没有 body、没有可用 encoder 时,非 GET 请求会走表单参数。
  • 有 body 或 encoder 时,使用 encoder 生成 body。

因此,实体请求建议明确写 @NamiBody/@Body,不要依赖参数猜测。

7、 如何选择

  • 浏览器、网关、跨语言:HTTP + JSON。
  • 强调长连接或 Socket.D 能力:单独学习 Socket.D,不要把 HTTP 配置照搬过去。
  • 内部高性能二进制协议:评估 Hessian、Fury、Kryo、Protostuff,并建立兼容性测试。

遇到 There is no channel available,先查 URL scheme 和 nami-channel-*;遇到 There is no matching decoder 或解码异常,再查 coder、Content-Type 和服务端 serialization。