Skip to content

Commit 23d3dd5

Browse files
committed
Simplify code. Use functions for handlers
1 parent e5a511b commit 23d3dd5

File tree

9 files changed

+135
-196
lines changed

9 files changed

+135
-196
lines changed

server/handler_connect.go

Lines changed: 0 additions & 20 deletions
This file was deleted.

server/handler_connect_test.go

Lines changed: 0 additions & 23 deletions
This file was deleted.

server/handler_method.go

Lines changed: 0 additions & 28 deletions
This file was deleted.

server/handler_method_test.go

Lines changed: 0 additions & 36 deletions
This file was deleted.

server/handler_ping.go

Lines changed: 0 additions & 30 deletions
This file was deleted.

server/handler_ping_test.go

Lines changed: 0 additions & 39 deletions
This file was deleted.

server/server.go

Lines changed: 49 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,13 @@ package server
33
import (
44
"encoding/json"
55
"errors"
6+
"fmt"
67
"net/http"
78

89
"github.com/gorilla/websocket"
10+
"github.com/meteorhacks/goddp/utils/random"
911
)
1012

11-
type Server struct {
12-
handlers map[string]Handler
13-
methods map[string]MethodFn
14-
upgrader websocket.Upgrader
15-
}
16-
1713
func New() Server {
1814
s := Server{}
1915
s.methods = make(map[string]MethodFn)
@@ -22,15 +18,14 @@ func New() Server {
2218
WriteBufferSize: 1024,
2319
}
2420

25-
s.handlers = map[string]Handler{
26-
"connect": NewConnectHandler(s),
27-
"ping": NewPingHandler(s),
28-
"method": NewMethodHandler(s),
29-
}
30-
3121
return s
3222
}
3323

24+
type Server struct {
25+
methods map[string]MethodFn
26+
upgrader websocket.Upgrader
27+
}
28+
3429
func (s *Server) Listen(addr string) {
3530
http.HandleFunc("/websocket", s.Handler)
3631
http.ListenAndServe(addr, nil)
@@ -48,15 +43,20 @@ func (s *Server) Handler(w http.ResponseWriter, r *http.Request) {
4843
}
4944

5045
for {
51-
msg, err := readMessage(req)
46+
msg, err := readMessage(ws)
5247

5348
if err != nil {
5449
break
5550
}
5651

57-
if h, ok := s.handlers[msg.Msg]; ok {
58-
go h.handle(res, msg)
59-
} else {
52+
switch msg.Msg {
53+
case "connect":
54+
handleConnect(s, ws, msg)
55+
case "ping":
56+
handlePing(s, ws, msg)
57+
case "method":
58+
handleMethod(s, ws, msg)
59+
default:
6060
// TODO => send "error" ddp message
6161
break
6262
}
@@ -84,3 +84,36 @@ func readMessage(req Request) (Message, error) {
8484

8585
return msg, nil
8686
}
87+
88+
func handleConnect(s *Server, res Response, m Message) error {
89+
return res.WriteJSON(map[string]string{
90+
"msg": "connected",
91+
"session": random.Id(17),
92+
})
93+
}
94+
95+
func handleMethod(s *Server, res Response, m Message) error {
96+
fn, ok := s.methods[m.Method]
97+
98+
if !ok {
99+
err := errors.New(fmt.Sprintf("method %s not found", m.Method))
100+
return err
101+
}
102+
103+
ctx := NewMethodContext(m, res)
104+
go fn(ctx)
105+
106+
return nil
107+
}
108+
109+
func handlePing(s *Server, res Response, m Message) error {
110+
msg := map[string]string{
111+
"msg": "pong",
112+
}
113+
114+
if m.ID != "" {
115+
msg["id"] = m.ID
116+
}
117+
118+
return res.WriteJSON(msg)
119+
}

server/server_test.go

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package server
22

33
import (
44
"errors"
5+
"reflect"
56
"testing"
67
)
78

@@ -48,3 +49,87 @@ func TestReadMessageValidMessage(t *testing.T) {
4849
t.Error("message must have correct message type")
4950
}
5051
}
52+
53+
func TestHandleConnect(t *testing.T) {
54+
s := &Server{}
55+
m := Message{}
56+
r := &TestResponse{}
57+
58+
if err := handleConnect(s, r, m); err != nil {
59+
t.Error("connect should be handled successfully")
60+
}
61+
62+
data := r._data.(map[string]string)
63+
if data["msg"] != "connected" {
64+
t.Error("msg field should be 'connected'")
65+
}
66+
67+
if len(data["session"]) != 17 {
68+
t.Error("session field should be have 17 characters")
69+
}
70+
}
71+
72+
func TestUnavailableMethod(t *testing.T) {
73+
s := &Server{}
74+
m := Message{Method: "test"}
75+
r := &TestResponse{}
76+
77+
if err := handleMethod(s, r, m); err == nil {
78+
t.Error("an error must be returned if method is not available")
79+
}
80+
}
81+
82+
func TestAvailableMethod(t *testing.T) {
83+
s := &Server{methods: make(map[string]MethodFn)}
84+
m := Message{Method: "test"}
85+
r := &TestResponse{}
86+
c := make(chan bool)
87+
88+
s.methods["test"] = func(ctx MethodContext) {
89+
c <- true
90+
}
91+
92+
if err := handleMethod(s, r, m); err != nil {
93+
t.Error("an error must not be returned if method is available")
94+
}
95+
96+
// block untill method is called
97+
<-c
98+
}
99+
100+
func TestHandlePingWithoutID(t *testing.T) {
101+
s := &Server{}
102+
m := Message{}
103+
r := &TestResponse{}
104+
105+
if err := handlePing(s, r, m); err != nil {
106+
t.Error("ping should be handled successfully")
107+
}
108+
109+
expected := map[string]string{
110+
"msg": "pong",
111+
}
112+
113+
if !reflect.DeepEqual(r._data, expected) {
114+
t.Error("message should only have msg field")
115+
}
116+
}
117+
118+
func TestHandlePingWithID(t *testing.T) {
119+
s := &Server{}
120+
m := Message{ID: "test-id"}
121+
r := &TestResponse{}
122+
123+
if err := handlePing(s, r, m); err != nil {
124+
t.Error("ping should be handled successfully")
125+
}
126+
127+
expected := map[string]string{
128+
"msg": "pong",
129+
"id": "test-id",
130+
}
131+
132+
if !reflect.DeepEqual(r._data, expected) {
133+
t.Error("message should have msg and ID fields")
134+
}
135+
}

server/types.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,8 @@ type Response interface {
88
WriteJSON(interface{}) error
99
}
1010

11-
type Handler interface {
12-
handle(Response, Message) error
13-
}
14-
1511
type MethodFn func(MethodContext)
12+
type Handler func(*Server, Response, Message) error
1613

1714
// This has the all the possible fields a DDP message can have
1815
type Message struct {

0 commit comments

Comments
 (0)