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.
4.6 KiB
4.6 KiB
服务端如何写数据到客户端
概述
nnet库提供了多种方式将数据从服务端写入到客户端,支持任意类型的数据,并自动匹配编解码器进行编码。
方式一:写入字节数据(基础方式)
func handler(ctx context.Context) error {
// 直接写入字节数据
data := []byte("Hello, World!")
return ctx.Write(data)
}
方式二:写入字符串
func handler(ctx context.Context) error {
// 写入字符串
return ctx.WriteString("Hello, World!")
}
方式三:写入任意类型(自动编码)⭐
这是最推荐的方式,支持任意类型的数据,会自动使用配置的编解码器进行编码。
基本使用
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)
}
指定编解码器
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、长度、校验和等)。
配置协议层编码
cfg := &nnet.Config{
Addr: "tcp://:8080",
Codec: &nnet.CodecConfig{
DefaultCodec: "json",
EnableProtocolEncode: true, // 启用协议层编码
},
}
server, err := nnet.NewServer(cfg)
使用示例
func handler(ctx context.Context) error {
// 数据会先使用JSON编码,然后使用协议编码(如nnet协议)
resp := Response{Code: 200, Message: "success"}
return ctx.WriteAny(resp)
}
完整示例
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")
}
支持的编解码器
-
JSON(可选,默认是 binary)
- 支持所有可序列化的Go类型
- 使用标准库的
encoding/json
-
Binary
- 支持基本数值类型和字节数组
- 使用二进制编码
-
Protobuf
- 需要实现
proto.Message接口 - 使用Google Protocol Buffers
- 需要实现
-
MessagePack
- 支持所有可序列化的Go类型
- 比JSON更紧凑的二进制格式
编解码器注册
服务器会自动注册以下编解码器:
json- JSON编解码器(可选;默认为 binary)binary- 二进制编解码器protobuf- Protobuf编解码器- `