Skip to content

Commit 5ab5605

Browse files
committed
Parse Events
1 parent f309330 commit 5ab5605

File tree

6 files changed

+90
-38
lines changed

6 files changed

+90
-38
lines changed

pkg/msg/msg.go

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package msg
22

33
import (
44
"encoding/json"
5+
"errors"
56
)
67

78
const (
@@ -11,8 +12,11 @@ const (
1112
// Response type code
1213
Response = 2
1314

14-
// Event type code
15-
Event = 3
15+
// EventPublic is public event type code
16+
EventPublic = 3
17+
18+
// EventPrivate is private event type code
19+
EventPrivate = 4
1620
)
1721

1822
// Msg represent websocket messages, it could be either a request, a response or an event
@@ -34,17 +38,26 @@ func NewResponse(req *Msg, method string, args []interface{}) *Msg {
3438
}
3539

3640
// Encode msg into json
37-
func (m *Msg) Encode() []byte {
38-
s, err := json.Marshal([]interface{}{
39-
m.Type,
40-
m.ReqID,
41-
m.Method,
42-
m.Args,
43-
})
44-
if err != nil {
45-
return []byte{}
41+
func (m *Msg) Encode() ([]byte, error) {
42+
switch m.Type {
43+
case Response, Request:
44+
return json.Marshal([]interface{}{
45+
m.Type,
46+
m.ReqID,
47+
m.Method,
48+
m.Args,
49+
})
50+
51+
case EventPrivate, EventPublic:
52+
return json.Marshal([]interface{}{
53+
m.Type,
54+
m.Method,
55+
m.Args,
56+
})
57+
58+
default:
59+
return nil, errors.New("invalid type")
4660
}
47-
return s
4861
}
4962

5063
// Convss2is converts a string slice to interface slice more details: https://golang.org/doc/faq#convert_slice_of_interface)

pkg/msg/msg_test.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,8 @@ func TestEncoding(t *testing.T) {
1414
Args: []interface{}{"hello", "there"},
1515
}
1616

17-
assert.Equal(t, `[1,42,"test",["hello","there"]]`, string(msg.Encode()))
17+
enc, err := msg.Encode()
18+
19+
assert.NoError(t, err)
20+
assert.Equal(t, `[1,42,"test",["hello","there"]]`, string(enc))
1821
}

pkg/msg/parser.go

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -73,37 +73,61 @@ func ParseSliceOfStrings(t interface{}) ([]string, error) {
7373

7474
func Parse(msg []byte) (*Msg, error) {
7575
req := Msg{}
76-
7776
var v []interface{}
7877
if err := json.Unmarshal(msg, &v); err != nil {
7978
return nil, fmt.Errorf("Could not parse message: %w", err)
8079
}
8180

82-
if len(v) != 4 {
83-
return nil, errors.New("message must contains 4 elements")
81+
if len(v) < 3 {
82+
return nil, errors.New("message is too small")
8483
}
8584

8685
t, err := ParseUint8(v[0])
8786
if err != nil {
8887
return nil, fmt.Errorf("failed to parse type: %w", err)
8988
}
90-
if t != Request && t != Response && t != Event {
91-
return nil, errors.New("message type must be 1, 2 or 3")
92-
}
9389

94-
reqID, err := ParseUint64(v[1])
95-
if err != nil {
96-
return nil, fmt.Errorf("failed to parse request ID: %w", err)
97-
}
90+
var reqID uint64
91+
var method string
92+
var args []interface{}
9893

99-
method, err := ParseString(v[2])
100-
if err != nil {
101-
return nil, fmt.Errorf("failed to parse method: %w", err)
102-
}
94+
switch t {
95+
case Request, Response:
96+
if len(v) != 4 {
97+
return nil, errors.New("message must contain 4 elements")
98+
}
10399

104-
args, err := ParseSlice(v[3])
105-
if err != nil {
106-
return nil, fmt.Errorf("failed to parse arguments: %w", err)
100+
reqID, err = ParseUint64(v[1])
101+
if err != nil {
102+
return nil, fmt.Errorf("failed to parse request ID: %w", err)
103+
}
104+
105+
method, err = ParseString(v[2])
106+
if err != nil {
107+
return nil, fmt.Errorf("failed to parse method: %w", err)
108+
}
109+
110+
args, err = ParseSlice(v[3])
111+
if err != nil {
112+
return nil, fmt.Errorf("failed to parse arguments: %w", err)
113+
}
114+
115+
case EventPrivate, EventPublic:
116+
if len(v) != 3 {
117+
return nil, errors.New("message must contain 3 elements")
118+
}
119+
120+
method, err = ParseString(v[1])
121+
if err != nil {
122+
return nil, fmt.Errorf("failed to parse method: %w", err)
123+
}
124+
125+
args, err = ParseSlice(v[2])
126+
if err != nil {
127+
return nil, fmt.Errorf("failed to parse arguments: %w", err)
128+
}
129+
default:
130+
return nil, errors.New("message type must be 1, 2, 3 or 4")
107131
}
108132

109133
req.Type = t

pkg/msg/parser_test.go

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,20 +27,20 @@ func TestParserSuccess(t *testing.T) {
2727
Args: []interface{}{},
2828
}, msg)
2929

30-
msg, err = Parse([]byte(`[3,42,"temperature",[28.7]]`))
30+
msg, err = Parse([]byte(`[3,"temperature",[28.7]]`))
3131
assert.NoError(t, err)
3232
assert.Equal(t,
3333
&Msg{
34-
Type: Event,
35-
ReqID: 42,
34+
Type: EventPublic,
35+
ReqID: 0,
3636
Method: "temperature",
3737
Args: []interface{}{28.7},
3838
}, msg)
3939
}
4040

4141
func TestParserErrorsMessageLength(t *testing.T) {
4242
msg, err := Parse([]byte(`[1,42,"ping"]`))
43-
assert.EqualError(t, err, "message must contains 4 elements")
43+
assert.EqualError(t, err, "message must contain 4 elements")
4444
assert.Nil(t, msg)
4545
}
4646

@@ -51,8 +51,12 @@ func TestParserErrorsBadJSON(t *testing.T) {
5151
}
5252

5353
func TestParserErrorsType(t *testing.T) {
54-
msg, err := Parse([]byte(`[4,42,"ping",[]]`))
55-
assert.EqualError(t, err, "message type must be 1, 2 or 3")
54+
msg, err := Parse([]byte(`[5,42,"ping",[]]`))
55+
assert.EqualError(t, err, "message type must be 1, 2, 3 or 4")
56+
assert.Nil(t, msg)
57+
58+
msg, err = Parse([]byte(`[5,"ping",[]]`))
59+
assert.EqualError(t, err, "message type must be 1, 2, 3 or 4")
5660
assert.Nil(t, msg)
5761

5862
msg, err = Parse([]byte(`[1.1,42,"pong",[]]`))

pkg/routing/client.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,12 @@ func (c *Client) read() {
194194
req, err := msg.Parse(message)
195195
if err != nil {
196196
log.Error().Msgf("fail to parse message: %s", err.Error())
197-
c.send <- msg.NewResponse(&msg.Msg{ReqID: 0}, "error", []interface{}{err.Error()}).Encode()
197+
198+
resp, err := msg.NewResponse(&msg.Msg{ReqID: 0}, "error", []interface{}{err.Error()}).Encode()
199+
if err == nil {
200+
c.send <- resp
201+
}
202+
198203
continue
199204
}
200205

pkg/routing/hub.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,10 @@ func (h *Hub) ListenWebsocketEvents() {
9595
select {
9696
case req := <-h.Requests:
9797
resp := h.handleRequest(&req)
98-
req.client.Send(string(resp.Encode()))
98+
encoded, err := resp.Encode()
99+
if err == nil {
100+
req.client.Send(string(encoded))
101+
}
99102

100103
case client := <-h.Unregister:
101104
log.Info().Msgf("Unregistering client %s", client.GetUID())

0 commit comments

Comments
 (0)