-
Notifications
You must be signed in to change notification settings - Fork 0
/
connhandler.go
105 lines (97 loc) 路 2.4 KB
/
connhandler.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package encoder
import (
"bytes"
"encoding/binary"
"encoding/gob"
"io"
"net"
"github.com/antontroskie/radrpc/pkg/rpc/itf"
"github.com/google/uuid"
"github.com/pkg/errors"
)
// EncodeMessage encodes a message.
func EncodeMessage(message any) ([]byte, error) {
var buffer bytes.Buffer
encoder := gob.NewEncoder(&buffer)
if err := encoder.Encode(message); err != nil {
return nil, errors.Wrap(err, "error encoding")
}
return buffer.Bytes(), nil
}
// DecodeMessage decodes a message.
func DecodeMessage[T any](data []byte) (T, error) {
var message T
if len(data) == 0 {
return message, nil
}
buffer := bytes.NewBuffer(data)
decoder := gob.NewDecoder(buffer)
if err := decoder.Decode(&message); err != nil {
return message, errors.Wrap(err, "error decoding")
}
return message, nil
}
// WriteHeartbeatRequest writes a heartbeat request.
func WriteHeartbeatRequest(conn net.Conn) error {
id := uuid.New().String()
msg := itf.RPCMessageReq{
ID: id,
Type: itf.HeartbeatRequest,
TimeStamp: 0,
Method: "",
Args: []any{},
}
data, err := EncodeMessage(msg)
if err != nil {
return err
}
return WriteMessage(conn, data)
}
// WriteHeartbeatResponse writes a heartbeat response.
func WriteHeartbeatResponse(conn net.Conn, id string) error {
msg := itf.RPCMessageRes{
ID: id,
Type: itf.HeartbeatResponse,
TimeStamp: 0,
ResponseError: "",
ResponseSuccess: nil,
}
data, err := EncodeMessage(msg)
if err != nil {
return err
}
return WriteMessage(conn, data)
}
// WriteMessage writes a message.
func WriteMessage(conn net.Conn, msg []byte) error {
length := uint64(len(msg))
if err := binary.Write(conn, binary.LittleEndian, length); err != nil {
return errors.Wrap(err, "error writing binary")
}
if len(msg) == 0 {
return nil
}
if _, err := conn.Write(msg); err != nil {
return errors.Wrap(err, "error writing message")
}
return nil
}
// ReadMessage reads a message.
func ReadMessage(conn net.Conn) ([]byte, error) {
var length uint64
if err := binary.Read(conn, binary.LittleEndian, &length); err != nil {
if errors.Is(err, io.EOF) {
return nil, errors.Wrap(err, "error reading binary")
}
}
if length == 0 {
return nil, nil
}
data := make([]byte, length)
if _, err := io.ReadFull(conn, data); err != nil {
if errors.Is(err, io.EOF) {
return nil, errors.Wrap(err, "error reading message")
}
}
return data, nil
}