forked from googollee/go-socket.io
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnamespace_handler.go
114 lines (94 loc) · 2.33 KB
/
namespace_handler.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
package socketio
import (
"errors"
"reflect"
"sync"
"github.com/googollee/go-socket.io/parser"
)
type namespaceHandler struct {
broadcast Broadcast
eventsMu sync.RWMutex
events map[string]*funcHandler
onConnect func(c Conn) error
onDisconnect func(c Conn, msg string)
onError func(c Conn, err error)
}
func newNamespaceHandler(nsp string, adapterOpts *RedisAdapterOptions) *namespaceHandler {
var broadcast Broadcast
if adapterOpts == nil {
broadcast = newBroadcast()
} else {
broadcast, _ = newRedisBroadcast(nsp, adapterOpts)
}
return &namespaceHandler{
broadcast: broadcast,
events: make(map[string]*funcHandler),
}
}
func (h *namespaceHandler) OnConnect(f func(Conn) error) {
h.onConnect = f
}
func (h *namespaceHandler) OnDisconnect(f func(Conn, string)) {
h.onDisconnect = f
}
func (h *namespaceHandler) OnError(f func(Conn, error)) {
h.onError = f
}
func (h *namespaceHandler) OnEvent(event string, f interface{}) {
h.eventsMu.Lock()
defer h.eventsMu.Unlock()
h.events[event] = newEventFunc(f)
}
func (h *namespaceHandler) getTypes(header parser.Header, event string) []reflect.Type {
switch header.Type {
case parser.Error:
fallthrough
case parser.Disconnect:
return []reflect.Type{reflect.TypeOf("")}
case parser.Event:
h.eventsMu.RLock()
namespaceHandler := h.events[event]
h.eventsMu.RUnlock()
if namespaceHandler == nil {
return nil
}
return namespaceHandler.argTypes
}
return nil
}
//todo maybe refactor this
func (h *namespaceHandler) dispatch(c Conn, header parser.Header, event string, args []reflect.Value) ([]reflect.Value, error) {
switch header.Type {
case parser.Connect:
if h.onConnect != nil {
return nil, h.onConnect(c)
}
return nil, nil
case parser.Disconnect:
var msg string
if len(args) > 0 {
msg = args[0].Interface().(string)
}
if h.onDisconnect != nil {
h.onDisconnect(c, msg)
}
return nil, nil
case parser.Error:
var msg string
if len(args) > 0 {
msg = args[0].Interface().(string)
}
if h.onError != nil {
h.onError(c, errors.New(msg))
}
case parser.Event:
h.eventsMu.RLock()
namespaceHandler := h.events[event]
h.eventsMu.RUnlock()
if namespaceHandler == nil {
return nil, nil
}
return namespaceHandler.Call(append([]reflect.Value{reflect.ValueOf(c)}, args...))
}
return nil, parser.ErrInvalidPacketType
}