# 服务端写数据到客户端 - 问题解答 ## 问题 1. 服务端如何写数据到客户端? 2. 是否支持any类型? 3. 通过协议自动匹配编码器? ## 答案 ### 1. 服务端如何写数据到客户端? nnet库提供了多种方式将数据从服务端写入到客户端: #### 方式一:直接写入字节数据 ```go func handler(ctx ctxpkg.Context) error { data := []byte("Hello, World!") return ctx.Write(data) } ``` #### 方式二:写入字符串 ```go func handler(ctx ctxpkg.Context) error { return ctx.WriteString("Hello, World!") } ``` #### 方式三:写入任意类型(自动编码)⭐ **推荐** ```go type Response struct { Code int `json:"code"` Message string `json:"message"` Data interface{} `json:"data"` } func handler(ctx ctxpkg.Context) error { resp := Response{ Code: 200, Message: "success", Data: map[string]interface{}{"user_id": 123}, } // 自动使用配置的默认编解码器(库默认是 binary) return ctx.WriteAny(resp) } ``` ### 2. 是否支持any类型? **是的,完全支持!** nnet库支持写入任意Go类型: - ✅ 结构体(struct) - ✅ 映射(map) - ✅ 切片(slice) - ✅ 数组(array) - ✅ 基本类型(int, string, bool等) - ✅ 接口类型(interface{}) 使用`ctx.WriteAny(data)`方法,nnet会自动: 1. 检测数据类型 2. 选择合适的编解码器 3. 编码数据 4. 写入客户端 ### 3. 通过协议自动匹配编码器? **是的,完全支持!** nnet库提供了**自动编解码器匹配**功能: #### 自动匹配机制 1. **默认编解码器**:根据配置自动选择默认编解码器(库默认 binary) ```go cfg := &nnet.Config{ Codec: &nnet.CodecConfig{ DefaultCodec: "json", // 显式使用JSON }, } ``` 2. **自动编码**:使用`WriteAny`时,自动使用默认编解码器(默认 binary) ```go ctx.WriteAny(data) // 自动使用JSON编码 ``` 3. **指定编解码器**:可以指定使用哪个编解码器 ```go ctx.WriteAnyWithCodec(data, "json") // 使用JSON ctx.WriteAnyWithCodec(data, "msgpack") // 使用MessagePack ctx.WriteAnyWithCodec(data, "protobuf") // 使用Protobuf ``` #### 协议层编码(可选) nnet还支持**协议层编码**,可以在编解码器编码的基础上,再进行协议层编码: ```go cfg := &nnet.Config{ Codec: &nnet.CodecConfig{ DefaultCodec: "json", EnableProtocolEncode: true, // 启用协议层编码 }, } ``` 启用后,数据会经过: 1. **编解码器编码**:Go对象 → JSON字节数组 2. **协议编码**:JSON字节数组 → nnet协议格式(包含Magic、长度、校验和等) ## 完整示例 ```go package main import ( "github.com/noahlann/nnet" ctxpkg "github.com/noahlann/nnet/pkg/context" ) type User struct { ID int `json:"id"` Name string `json:"name"` } type Response struct { Code int `json:"code"` Data interface{} `json:"data"` } func main() { // 配置服务器(启用自动编解码器匹配) cfg := &nnet.Config{ Addr: "tcp://:8080", Codec: &nnet.CodecConfig{ DefaultCodec: "json", // 显式使用JSON EnableProtocolEncode: false, // 不启用协议层编码 }, } // 创建服务器 server, err := nnet.NewServer(cfg) if err != nil { panic(err) } // 注册路由处理器 server.Router().RegisterString("get_user", func(ctx ctxpkg.Context) error { user := User{ID: 1, Name: "Alice"} resp := Response{Code: 200, Data: user} // 方式1:自动使用JSON编码(推荐) return ctx.WriteAny(resp) // 方式2:指定使用MessagePack编码 // return ctx.WriteAnyWithCodec(resp, "msgpack") // 方式3:直接写入字符串 // return ctx.WriteString("Hello, World!") }) // 启动服务器 server.Start() } ``` ## 支持的编解码器 nnet库自动注册以下编解码器: - **JSON**(可选,默认 binary):支持所有可序列化的Go类型 - **Binary**:支持基本数值类型和字节数组 - **Protobuf**:需要实现`proto.Message`接口 - **MessagePack**:支持所有可序列化的Go类型 ## 自定义编解码器 ```go // 注册自定义编解码器 server.CodecRegistry().Register("mycodec", myCodec) // 使用自定义编解码器 ctx.WriteAnyWithCodec(data, "mycodec") ``` ## 总结 ✅ **服务端写数据**:支持`Write`、`WriteString`、`WriteAny`三种方式 ✅ **支持any类型**:完全支持任意Go类型 ✅ **自动匹配编码器**:根据配置自动选择编解码器,也可以手动指定 ✅ **协议层编码**:可选地支持协议层编码(如nnet协议) 所有功能已实现并测试通过!