You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

196 lines
4.9 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 服务端写数据到客户端 - 问题解答
## 问题
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协议
所有功能已实现并测试通过!