-
Notifications
You must be signed in to change notification settings - Fork 411
/
message.go
164 lines (151 loc) · 4.94 KB
/
message.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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
package erpc
import (
"strconv"
"github.com/andeya/erpc/v7/codec"
"github.com/andeya/erpc/v7/socket"
"github.com/andeya/erpc/v7/utils"
"github.com/andeya/goutil"
)
// Message types
const (
TypeUndefined byte = 0
TypeCall byte = 1
TypeReply byte = 2 // reply to call
TypePush byte = 3
TypeAuthCall byte = 4
TypeAuthReply byte = 5
)
// TypeText returns the message type text.
// If the type is undefined returns 'Undefined'.
func TypeText(typ byte) string {
switch typ {
case TypeCall:
return "CALL"
case TypeReply:
return "REPLY"
case TypePush:
return "PUSH"
case TypeAuthCall:
return "AUTH_CALL"
case TypeAuthReply:
return "AUTH_REPLY"
default:
return "Undefined"
}
}
type (
// Socket is a generic stream-oriented network connection.
// NOTE:
// Multiple goroutines may invoke methods on a Socket simultaneously.
Socket = socket.Socket
// Proto pack/unpack protocol scheme of socket message.
Proto = socket.Proto
// ProtoFunc function used to create a custom Proto interface.
ProtoFunc = socket.ProtoFunc
// IOWithReadBuffer implements buffered I/O with buffered reader.
IOWithReadBuffer = socket.IOWithReadBuffer
)
type (
// Message a socket message data.
Message = socket.Message
// Header message header interface
Header = socket.Header
// Body message body interface
Body = socket.Body
// NewBodyFunc creates a new body by header.
NewBodyFunc = socket.NewBodyFunc
// MessageSetting is a pipe function type for setting message.
MessageSetting = socket.MessageSetting
)
const (
// MetaRealIP real IP metadata key
MetaRealIP = "X-Real-IP"
// MetaAcceptBodyCodec the key of body codec that the sender wishes to accept
MetaAcceptBodyCodec = "X-Accept-Body-Codec"
)
var (
// GetMessage gets a Message form message pool.
// NOTE:
// newBodyFunc is only for reading form connection;
// settings are only for writing to connection.
// func GetMessage(settings ...MessageSetting) Message
GetMessage = socket.GetMessage
// PutMessage puts a Message to message pool.
// func PutMessage(m Message)
PutMessage = socket.PutMessage
)
var (
// WithNothing nothing to do.
// func WithNothing() MessageSetting
WithNothing = socket.WithNothing
// WithStatus sets the message status.
// TYPE:
// func WithStatus(stat *Status) MessageSetting
WithStatus = socket.WithStatus
// WithContext sets the message handling context.
// func WithContext(ctx context.Context) MessageSetting
WithContext = socket.WithContext
// WithServiceMethod sets the message service method.
// SUGGEST: max len ≤ 255!
// func WithServiceMethod(serviceMethod string) MessageSetting
WithServiceMethod = socket.WithServiceMethod
// WithAddMeta adds 'key=value' metadata argument.
// Multiple values for the same key may be added.
// SUGGEST: urlencoded string max len ≤ 65535!
// func WithAddMeta(key, value string) MessageSetting
WithAddMeta = socket.WithAddMeta
// WithSetMeta sets 'key=value' metadata argument.
// SUGGEST: urlencoded string max len ≤ 65535!
// func WithSetMeta(key, value string) MessageSetting
WithSetMeta = socket.WithSetMeta
// WithDelMeta deletes metadata argument.
// func WithDelMeta(key string) MessageSetting
WithDelMeta = socket.WithDelMeta
// WithBodyCodec sets the body codec.
// func WithBodyCodec(bodyCodec byte) MessageSetting
WithBodyCodec = socket.WithBodyCodec
// WithBody sets the body object.
// func WithBody(body interface{}) MessageSetting
WithBody = socket.WithBody
// WithNewBody resets the function of geting body.
// NOTE: newBodyFunc is only for reading form connection.
// func WithNewBody(newBodyFunc socket.NewBodyFunc) MessageSetting
WithNewBody = socket.WithNewBody
// WithXferPipe sets transfer filter pipe.
// NOTE: Panic if the filterID is not registered.
// SUGGEST: The length can not be bigger than 255!
// func WithXferPipe(filterID ...byte) MessageSetting
WithXferPipe = socket.WithXferPipe
)
// WithRealIP sets the real IP to metadata.
func WithRealIP(ip string) MessageSetting {
return socket.WithAddMeta(MetaRealIP, ip)
}
// WithAcceptBodyCodec sets the body codec that the sender wishes to accept.
// NOTE: If the specified codec is invalid, the receiver will ignore the mate data.
func WithAcceptBodyCodec(bodyCodec byte) MessageSetting {
if bodyCodec == codec.NilCodecID {
return WithNothing()
}
return socket.WithAddMeta(MetaAcceptBodyCodec, strconv.FormatUint(uint64(bodyCodec), 10))
}
// withMtype sets the message type.
func withMtype(mtype byte) MessageSetting {
return func(m Message) {
m.SetMtype(mtype)
}
}
// GetAcceptBodyCodec gets the body codec that the sender wishes to accept.
// NOTE: If the specified codec is invalid, the receiver will ignore the mate data.
func GetAcceptBodyCodec(meta *utils.Args) (byte, bool) {
s := meta.Peek(MetaAcceptBodyCodec)
if len(s) == 0 || len(s) > 3 {
return 0, false
}
b, err := strconv.ParseUint(goutil.BytesToString(s), 10, 8)
if err != nil {
return 0, false
}
c := byte(b)
return c, c != codec.NilCodecID
}