手搓 RPC 框架 -- #4 序列化
支持不同的序列化协议
- Encode:将数据转化为字节
- Decode:将字节转化为数据
- Code:用一个字节来表达这种序列化协议,需要在客户端和服务端之间协商一致。例如用 1 来代表 JSON 序列化协议。
package serialize
type Serializer interface {
Code() uint8
Encode(val any) ([]byte, error)
// Decode val 是一个结构体指针
Decode(data []byte, val any) error
}
JSON 序列化协议
package json
import jsoniter "github.com/json-iterator/go"
type Serializer struct {
}
func (s *Serializer) Code() uint8 {
return 1
}
func (s *Serializer) Encode(val any) ([]byte, error) {
return jsoniter.Marshal(val)
}
func (s *Serializer) Decode(data []byte, val any) error {
return jsoniter.Unmarshal(data, val)
}
Proto 序列化协议
package proto
import (
"errors"
"google.golang.org/protobuf/proto"
)
type Serializer struct {
}
func (s *Serializer) Code() uint8 {
return 2
}
func (s *Serializer) Encode(val any) ([]byte, error) {
msg, ok := val.(proto.Message)
if !ok {
return nil, errors.New("micro: val must be proto.Message")
}
return proto.Marshal(msg)
}
func (s *Serializer) Decode(data []byte, val any) error {
msg, ok := val.(proto.Message)
if !ok {
return errors.New("micro: val must be proto.Message")
}
return proto.Unmarshal(data, msg)
}
客户端初始化
type Client struct {
pool pool.Pool
serializer serialize.Serializer
}
type ClientOption func(client *Client)
func ClientWithSerializer(sl serialize.Serializer) ClientOption {
return func(client *Client) {
client.serializer = sl
}
}
func NewClient(network, addr string, opts ...ClientOption) (*Client, error) {
p, err := pool.NewChannelPool(
&pool.Config{
InitialCap: 1,
MaxCap: 30,
MaxIdle: 10,
IdleTimeout: time.Minute,
Factory: func() (interface{}, error) {
return net.DialTimeout(network, addr, time.Second*3)
},
Close: func(i interface{}) error {
return i.(net.Conn).Close()
},
},
)
if err != nil {
return nil, err
}
c := &Client{
pool: p,
serializer: &json.Serializer{},
}
for _, opt := range opts {
opt(c)
}
return c, nil
}
服务端初始化
type Server struct {
stubs map[string]reflectionStub
serializers map[uint8]serialize.Serializer
}
func NewServer() *Server {
s := &Server{
stubs: make(map[string]reflectionStub, 16),
serializers: make(map[uint8]serialize.Serializer, 4),
}
s.RegisterSerializer(&json.Serializer{})
return s
}
func (s *Server) RegisterSerializer(sl serialize.Serializer) {
s.serializers[sl.Code()] = sl
}
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。