-
Notifications
You must be signed in to change notification settings - Fork 0
/
types.go
227 lines (198 loc) · 4.66 KB
/
types.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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
package chat
import (
"crypto/sha1"
"github.com/google/uuid"
"github.com/tendermint/go-amino"
"io"
"time"
)
/*
值 含义 描述
0 打开会话 成功创建连接后,5秒内必须要发送此类型请求打开会话,否则将被断开
1 普通聊天 此类型消息用于1对1聊天场景
2 群聊 此类型消息用于1对多聊天场景
3 状态同步 可以实现消息的事件同步,例如:已送达、已读 等
4 系统消息 服务端返回给客户端的通知
5 RTP拨号 P2P服务拨号
6 暂无 预留
7 订阅 发布/订阅
*/
const (
NormalMsg MsgType = iota + 1
GroupMsg
SyncMsg
SysMsg
RtpMsg
BakMsg
PubsubMsg
)
const (
NoACK byte = iota
ACK
)
const MAX_PKG = 2048
/*
{
"envelope":{
"id":"UUID,要求必须唯一"
"from":"发送人JID",
"to":"接收人JID",
"type":"int型,含义是 消息类型",
"ack":"int型,0 或空是不必响应,1 必须响应",
"ct":"13位时间戳,由服务器来补充此值",
"pwd":"只有当 type=0 时,即 opensession 时,才会使用此属性",
"gid":"群ID,只在 type=2 时会用到此属性"
},
"vsn":"消息版本(预留属性)",
"payload":{
"attrs":{"k":"v",...},
"content":"..."
}
}
*/
//omitempty
type (
Msg interface {
FromBytes(data []byte) (Msg, error)
FromReader(r io.Reader) (Msg, error)
Bytes() []byte
FromJson(data []byte) (Msg, error)
Json() []byte
}
MsgHandle func(service *ChatService, msg *Message)
MsgType int
JID string // jid = "peerid + mailboxid" , 其中 mailboxid 可选
GID string // gid = "groupid + mailboxid"
Envelope struct {
Id string `json:"id,omitempty"`
From JID `json:"from,omitempty"`
To JID `json:"to,omitempty"`
Type MsgType `json:"type"`
Ack byte `json:"ack,omitempty"`
Ct int64 `json:"ct,omitempty"`
Gid JID `json:"gid,omitempty"`
}
Attr struct {
Key string `json:"key"`
Val string `json:"val"`
}
Payload struct {
Attrs []Attr `json:"attrs,omitempty"`
Content string `json:"content,omitempty"`
}
Message struct {
Envelope Envelope `json:"envelope"`
Payload Payload `json:"payload,omitempty"`
Vsn string `json:"vsn,omitempty"`
}
MessageBag struct {
Messages MessageList
}
MessageList []*Message
CleanMsg struct {
Jid JID
Ids []string
}
)
func (m MessageList) Len() int {
return len(m)
}
func (m MessageList) Less(i, j int) bool {
return m[i].Envelope.Ct < m[j].Envelope.Ct
}
func (m MessageList) Swap(i, j int) {
m[i], m[j] = m[j], m[i]
}
func (c *MessageBag) FromBytes(data []byte) (Msg, error) {
return c, amino.UnmarshalBinaryLengthPrefixed(data, c)
}
func (c *MessageBag) FromReader(r io.Reader) (Msg, error) {
_, err := amino.UnmarshalBinaryLengthPrefixedReader(r, c, MAX_PKG)
return c, err
}
func (c *MessageBag) Bytes() []byte {
data, _ := amino.MarshalBinaryLengthPrefixed(c)
return data
}
func (c *MessageBag) FromJson(data []byte) (Msg, error) {
err := amino.UnmarshalJSON(data, c)
return c, err
}
func (c *MessageBag) Json() []byte {
d, _ := amino.MarshalJSON(c)
return d
}
func NewJID(id, mailbox string) JID {
if mailbox != "" {
return JID(id + mailbox)
}
return JID(id)
}
func NewNormalMessage(from, to JID, content string, attr ...Attr) *Message {
return newMessage(from, to, "", content, NormalMsg, attr...)
}
func NewSysMessage(id string, attr ...Attr) *Message {
return newMessage("", "", id, "", SysMsg, attr...)
}
func newMessage(from, to JID, id, content string, mt MsgType, attr ...Attr) *Message {
envelope := Envelope{
Id: uuid.New().String(),
Type: mt,
Ack: NoACK,
Ct: time.Now().Unix(),
}
if id != "" {
envelope.Id = id
}
if from != "" {
envelope.From = from
}
if to != "" {
envelope.To = to
}
m := &Message{
Envelope: envelope,
Payload: Payload{
Content: content,
Attrs: attr,
},
Vsn: "0.0.2",
}
return m
}
func (i JID) Peerid() string {
if len(i) < 53 {
return ""
}
return string(i)[:53]
}
func (i JID) Mailid() string {
if len(i) < 53*2 {
return ""
}
return string(i)[53 : 53*2]
}
func (c *Message) FromBytes(data []byte) (Msg, error) {
return c, amino.UnmarshalBinaryLengthPrefixed(data, c)
}
func (c *Message) FromReader(r io.Reader) (Msg, error) {
_, err := amino.UnmarshalBinaryLengthPrefixedReader(r, c, MAX_PKG)
return c, err
}
func (c *Message) Bytes() []byte {
data, _ := amino.MarshalBinaryLengthPrefixed(c)
return data
}
func (c *Message) Hash() []byte {
s1 := sha1.New()
s1.Write(c.Bytes())
return s1.Sum(nil)
}
func (c *Message) FromJson(data []byte) (Msg, error) {
err := amino.UnmarshalJSON(data, c)
return c, err
}
func (c *Message) Json() []byte {
d, _ := amino.MarshalJSON(c)
return d
}