|
|
# 服务端如何写数据到客户端
|
|
|
|
|
|
## 概述
|
|
|
|
|
|
nnet库提供了多种方式将数据从服务端写入到客户端,支持任意类型的数据,并自动匹配编解码器进行编码。
|
|
|
|
|
|
## 方式一:写入字节数据(基础方式)
|
|
|
|
|
|
```go
|
|
|
func handler(ctx context.Context) error {
|
|
|
// 直接写入字节数据
|
|
|
data := []byte("Hello, World!")
|
|
|
return ctx.Write(data)
|
|
|
}
|
|
|
```
|
|
|
|
|
|
## 方式二:写入字符串
|
|
|
|
|
|
```go
|
|
|
func handler(ctx context.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 context.Context) error {
|
|
|
// 写入结构体(自动使用JSON编码)
|
|
|
resp := Response{
|
|
|
Code: 200,
|
|
|
Message: "success",
|
|
|
Data: map[string]interface{}{"user_id": 123},
|
|
|
}
|
|
|
return ctx.WriteAny(resp)
|
|
|
}
|
|
|
```
|
|
|
|
|
|
### 指定编解码器
|
|
|
|
|
|
```go
|
|
|
func handler(ctx context.Context) error {
|
|
|
resp := Response{
|
|
|
Code: 200,
|
|
|
Message: "success",
|
|
|
}
|
|
|
|
|
|
// 使用JSON编解码器
|
|
|
ctx.WriteAnyWithCodec(resp, "json")
|
|
|
|
|
|
// 使用MessagePack编解码器
|
|
|
ctx.WriteAnyWithCodec(resp, "msgpack")
|
|
|
|
|
|
// 使用Protobuf编解码器(需要实现proto.Message接口)
|
|
|
ctx.WriteAnyWithCodec(resp, "protobuf")
|
|
|
|
|
|
return nil
|
|
|
}
|
|
|
```
|
|
|
|
|
|
## 方式四:协议层编码(可选)
|
|
|
|
|
|
如果启用了协议层编码,数据会先使用编解码器编码,然后再使用协议编码(如nnet协议的Magic、长度、校验和等)。
|
|
|
|
|
|
### 配置协议层编码
|
|
|
|
|
|
```go
|
|
|
cfg := &nnet.Config{
|
|
|
Addr: "tcp://:8080",
|
|
|
Codec: &nnet.CodecConfig{
|
|
|
DefaultCodec: "json",
|
|
|
EnableProtocolEncode: true, // 启用协议层编码
|
|
|
},
|
|
|
}
|
|
|
|
|
|
server, err := nnet.NewServer(cfg)
|
|
|
```
|
|
|
|
|
|
### 使用示例
|
|
|
|
|
|
```go
|
|
|
func handler(ctx context.Context) error {
|
|
|
// 数据会先使用JSON编码,然后使用协议编码(如nnet协议)
|
|
|
resp := Response{Code: 200, Message: "success"}
|
|
|
return ctx.WriteAny(resp)
|
|
|
}
|
|
|
```
|
|
|
|
|
|
## 完整示例
|
|
|
|
|
|
```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", getUserHandler)
|
|
|
server.Router().RegisterString("list_users", listUsersHandler)
|
|
|
|
|
|
// 启动服务器
|
|
|
server.Start()
|
|
|
}
|
|
|
|
|
|
// 处理器1:返回单个用户(使用默认编解码器,binary)
|
|
|
func getUserHandler(ctx ctxpkg.Context) error {
|
|
|
user := User{
|
|
|
ID: 1,
|
|
|
Name: "Alice",
|
|
|
}
|
|
|
|
|
|
resp := Response{
|
|
|
Code: 200,
|
|
|
Data: user,
|
|
|
}
|
|
|
|
|
|
// 自动使用JSON编码
|
|
|
return ctx.WriteAny(resp)
|
|
|
}
|
|
|
|
|
|
// 处理器2:返回用户列表
|
|
|
func listUsersHandler(ctx ctxpkg.Context) error {
|
|
|
users := []User{
|
|
|
{ID: 1, Name: "Alice"},
|
|
|
{ID: 2, Name: "Bob"},
|
|
|
}
|
|
|
|
|
|
resp := Response{
|
|
|
Code: 200,
|
|
|
Data: users,
|
|
|
}
|
|
|
|
|
|
return ctx.WriteAny(resp)
|
|
|
}
|
|
|
|
|
|
// 处理器3:使用指定的编解码器
|
|
|
func getUserWithMsgpack(ctx ctxpkg.Context) error {
|
|
|
user := User{ID: 1, Name: "Alice"}
|
|
|
resp := Response{Code: 200, Data: user}
|
|
|
|
|
|
// 使用MessagePack编码
|
|
|
return ctx.WriteAnyWithCodec(resp, "msgpack")
|
|
|
}
|
|
|
```
|
|
|
|
|
|
## 支持的编解码器
|
|
|
|
|
|
1. **JSON**(可选,默认是 binary)
|
|
|
- 支持所有可序列化的Go类型
|
|
|
- 使用标准库的`encoding/json`
|
|
|
|
|
|
2. **Binary**
|
|
|
- 支持基本数值类型和字节数组
|
|
|
- 使用二进制编码
|
|
|
|
|
|
3. **Protobuf**
|
|
|
- 需要实现`proto.Message`接口
|
|
|
- 使用Google Protocol Buffers
|
|
|
|
|
|
4. **MessagePack**
|
|
|
- 支持所有可序列化的Go类型
|
|
|
- 比JSON更紧凑的二进制格式
|
|
|
|
|
|
## 编解码器注册
|
|
|
|
|
|
服务器会自动注册以下编解码器:
|
|
|
- `json` - JSON编解码器(可选;默认为 binary)
|
|
|
- `binary` - 二进制编解码器
|
|
|
- `protobuf` - Protobuf编解码器
|
|
|
- ` |