feat: implement codec

This commit is contained in:
2022-04-22 20:50:58 +08:00
parent 9083504cfc
commit cf8fa335a6
9 changed files with 332 additions and 0 deletions

34
codec/codec.go Normal file
View File

@ -0,0 +1,34 @@
package codec
import "io"
type Header struct {
ServiceMethod string
Seq uint64
Error string
}
type Codec interface {
io.Closer
ReadHeader(*Header) error
ReadBody(interface{}) error
Write(*Header, interface{}) error
}
type NewCodecFunc func(closer io.ReadWriteCloser) Codec
type Type string
const (
MagicNumber = 0x12E7165
GobType Type = "application/gob"
JsonType Type = "application/json"
)
var NewCodecFuncMap map[Type]NewCodecFunc
func init() {
NewCodecFuncMap = make(map[Type]NewCodecFunc)
NewCodecFuncMap[GobType] = NewGobCodec
NewCodecFuncMap[JsonType] = NewJsonCodec
}

56
codec/gob.go Normal file
View File

@ -0,0 +1,56 @@
package codec
import (
"bufio"
"encoding/gob"
"fmt"
"io"
)
type GobCodec struct {
conn io.ReadWriteCloser
buf *bufio.Writer
dec *gob.Decoder
enc *gob.Encoder
}
var _ Codec = (*GobCodec)(nil)
func NewGobCodec(conn io.ReadWriteCloser) Codec {
buf := bufio.NewWriter(conn)
return &GobCodec{
conn: conn,
buf: buf,
dec: gob.NewDecoder(conn),
enc: gob.NewEncoder(buf),
}
}
func (c *GobCodec) ReadHeader(h *Header) error {
return c.dec.Decode(h)
}
func (c *GobCodec) ReadBody(body interface{}) error {
return c.dec.Decode(body)
}
func (c *GobCodec) Write(h *Header, body interface{}) (err error) {
defer func() {
_ = c.buf.Flush()
if err != nil {
_ = c.Close()
}
}()
if err = c.enc.Encode(h); err != nil {
return fmt.Errorf("rpc codec: gob error encoding header: %v", err)
}
if err = c.enc.Encode(body); err != nil {
return fmt.Errorf("rpc codec: gob error encoding body: %v", err)
}
return nil
}
func (c *GobCodec) Close() error {
return c.conn.Close()
}

55
codec/json.go Normal file
View File

@ -0,0 +1,55 @@
package codec
import (
"bufio"
"encoding/json"
"fmt"
"io"
)
type JsonCodec struct {
conn io.ReadWriteCloser
buf *bufio.Writer
dec *json.Decoder
enc *json.Encoder
}
func (j *JsonCodec) Close() error {
return j.conn.Close()
}
func (j *JsonCodec) ReadHeader(h *Header) error {
return j.dec.Decode(h)
}
func (j *JsonCodec) ReadBody(body interface{}) error {
return j.dec.Decode(body)
}
func (j *JsonCodec) Write(header *Header, body interface{}) (err error) {
defer func() {
_ = j.buf.Flush()
if err != nil {
_ = j.Close()
}
}()
if err = j.enc.Encode(header); err != nil {
return fmt.Errorf("rpc codec: json error encoding header: %v", err)
}
if err = j.enc.Encode(body); err != nil {
return fmt.Errorf("rpc codec: json error encoding body: %v", err)
}
return nil
}
var _ Codec = (*JsonCodec)(nil)
func NewJsonCodec(conn io.ReadWriteCloser) Codec {
buf := bufio.NewWriter(conn)
return &JsonCodec{
conn: conn,
buf: buf,
dec: json.NewDecoder(conn),
enc: json.NewEncoder(buf),
}
}