-
Notifications
You must be signed in to change notification settings - Fork 1
/
handler.go
117 lines (94 loc) · 2.23 KB
/
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
115
116
117
package etp
import (
"context"
"sync"
"github.com/txix-open/etp/v3/msg"
)
type Handler interface {
Handle(ctx context.Context, conn *Conn, event msg.Event) []byte
}
type HandlerFunc func(ctx context.Context, conn *Conn, event msg.Event) []byte
func (h HandlerFunc) Handle(ctx context.Context, conn *Conn, event msg.Event) []byte {
return h(ctx, conn, event)
}
type ConnectHandler func(conn *Conn)
type DisconnectHandler func(conn *Conn, err error)
type ErrorHandler func(conn *Conn, err error)
type mux struct {
handlers map[string]Handler
onUnknownEvent Handler
onConnect ConnectHandler
onDisconnect DisconnectHandler
onError ErrorHandler
readLock sync.Locker
writeLock sync.Locker
}
func newMux() *mux {
lock := &sync.RWMutex{}
return &mux{
handlers: make(map[string]Handler),
readLock: lock.RLocker(),
writeLock: lock,
}
}
func (m *mux) On(event string, handler Handler) {
m.writeLock.Lock()
m.handlers[event] = handler
m.writeLock.Unlock()
}
func (m *mux) OnConnect(handler ConnectHandler) {
m.writeLock.Lock()
m.onConnect = handler
m.writeLock.Unlock()
}
func (m *mux) OnDisconnect(handler DisconnectHandler) {
m.writeLock.Lock()
m.onDisconnect = handler
m.writeLock.Unlock()
}
func (m *mux) OnError(handler ErrorHandler) {
m.writeLock.Lock()
m.onError = handler
m.writeLock.Unlock()
}
func (m *mux) OnUnknownEvent(handler Handler) {
m.writeLock.Lock()
m.onUnknownEvent = handler
m.writeLock.Unlock()
}
func (m *mux) handle(ctx context.Context, conn *Conn, event msg.Event) []byte {
m.readLock.Lock()
handler, ok := m.handlers[event.Name]
if !ok {
handler = m.onUnknownEvent
}
m.readLock.Unlock()
if handler != nil {
return handler.Handle(ctx, conn, event)
}
return nil
}
func (m *mux) handleConnect(conn *Conn) {
m.readLock.Lock()
onConnect := m.onConnect
m.readLock.Unlock()
if onConnect != nil {
onConnect(conn)
}
}
func (m *mux) handleDisconnect(conn *Conn, err error) {
m.readLock.Lock()
onDisconnect := m.onDisconnect
m.readLock.Unlock()
if onDisconnect != nil {
onDisconnect(conn, err)
}
}
func (m *mux) handleError(conn *Conn, err error) {
m.readLock.Lock()
onError := m.onError
m.readLock.Unlock()
if onError != nil {
onError(conn, err)
}
}