feat: implement codec
This commit is contained in:
34
codec/codec.go
Normal file
34
codec/codec.go
Normal 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
56
codec/gob.go
Normal 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
55
codec/json.go
Normal 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),
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user