-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnamespace.go
112 lines (92 loc) · 2.29 KB
/
namespace.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
package sio
import (
"github.com/funcards/engine.io"
"github.com/funcards/socket.io-parser/v5"
"go.uber.org/atomic"
"go.uber.org/zap"
"sync"
)
var _ Namespace = (*namespace)(nil)
type Namespace interface {
eio.Emitter
NextAckID() uint64
Name() string
Server() Server
Adapter() Adapter
Add(client Client, data any) Socket
Remove(sck Socket)
AddConnected(sck Socket)
RemoveConnected(sck Socket)
ConnectedSockets() map[string]Socket
Broadcast(rooms []string, event string, args ...any)
}
type namespace struct {
eio.Emitter
ackID *atomic.Uint64
name string
srv Server
adapter Adapter
log *zap.Logger
sockets *sync.Map
connSockets *sync.Map
}
func NewNamespace(name string, srv Server, logger *zap.Logger) *namespace {
n := &namespace{
Emitter: eio.NewEmitter(),
ackID: atomic.NewUint64(0),
name: name,
srv: srv,
log: logger,
sockets: new(sync.Map),
connSockets: new(sync.Map),
}
n.adapter = srv.AdapterFactory()(n)
return n
}
func (n *namespace) NextAckID() uint64 {
return n.ackID.Inc()
}
func (n *namespace) Name() string {
return n.name
}
func (n *namespace) Server() Server {
return n.srv
}
func (n *namespace) Adapter() Adapter {
return n.adapter
}
func (n *namespace) Add(client Client, data any) Socket {
sck := NewSocket(n, client, data, n.log)
if client.Conn().State() == eio.Open {
n.log.Debug("namespace: add new connection", zap.String("nsp", n.Name()), zap.Any("data", data))
n.sockets.Store(sck.SID(), sck)
sck.OnConnect()
n.Fire(eio.TopicConnection, sck)
}
return sck
}
func (n *namespace) Remove(sck Socket) {
n.sockets.Delete(sck.SID())
}
func (n *namespace) AddConnected(sck Socket) {
n.connSockets.Store(sck.SID(), sck)
}
func (n *namespace) RemoveConnected(sck Socket) {
n.connSockets.Delete(sck.SID())
}
func (n *namespace) ConnectedSockets() map[string]Socket {
data := map[string]Socket{}
n.connSockets.Range(func(key, value any) bool {
data[key.(string)] = value.(Socket)
return true
})
return data
}
func (n *namespace) Broadcast(rooms []string, event string, args ...any) {
if len(event) == 0 {
n.log.Warn("namespace: broadcast event is empty")
return
}
packet := CreateDataPacket(siop.Event, event, args...)
n.adapter.Broadcast(packet, rooms)
}