-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
perf: 优化 server.Server 连接管理机制,优化 GetOnlineCount、GetOnlineBotCount 性能
- Loading branch information
1 parent
f8d8d37
commit 5e5fe8a
Showing
4 changed files
with
159 additions
and
51 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
package server | ||
|
||
import ( | ||
"context" | ||
"github.com/kercylan98/minotaur/utils/hash" | ||
"sync" | ||
) | ||
|
||
type hub struct { | ||
connections map[string]*Conn // 所有连接 | ||
|
||
register chan *Conn // 注册连接 | ||
unregister chan string // 注销连接 | ||
broadcast chan hubBroadcast // 广播消息 | ||
|
||
botCount int // 机器人数量 | ||
onlineCount int // 在线人数 | ||
|
||
chanMutex sync.RWMutex // 避免外界函数导致的并发问题 | ||
} | ||
|
||
type hubBroadcast struct { | ||
packet []byte // 广播的数据包 | ||
filter func(conn *Conn) bool // 过滤掉返回 false 的连接 | ||
} | ||
|
||
func (h *hub) run(ctx context.Context) { | ||
h.connections = make(map[string]*Conn) | ||
h.register = make(chan *Conn, DefaultConnHubBufferSize) | ||
h.unregister = make(chan string, DefaultConnHubBufferSize) | ||
h.broadcast = make(chan hubBroadcast, DefaultConnHubBufferSize) | ||
go func(ctx context.Context, h *hub) { | ||
for { | ||
select { | ||
case conn := <-h.register: | ||
h.chanMutex.Lock() | ||
h.connections[conn.GetID()] = conn | ||
h.onlineCount++ | ||
if conn.IsBot() { | ||
h.botCount++ | ||
} | ||
h.chanMutex.Unlock() | ||
case connId := <-h.unregister: | ||
h.chanMutex.Lock() | ||
if conn, ok := h.connections[connId]; ok { | ||
h.onlineCount-- | ||
delete(h.connections, conn.GetID()) | ||
if conn.IsBot() { | ||
h.botCount-- | ||
} | ||
} | ||
h.chanMutex.Unlock() | ||
case packet := <-h.broadcast: | ||
h.chanMutex.RLock() | ||
for _, conn := range h.connections { | ||
if packet.filter != nil && !packet.filter(conn) { | ||
continue | ||
} | ||
conn.Write(packet.packet) | ||
} | ||
|
||
case <-ctx.Done(): | ||
h.chanMutex.Lock() | ||
close(h.register) | ||
close(h.unregister) | ||
h.connections = nil | ||
h.botCount = 0 | ||
h.onlineCount = 0 | ||
h.chanMutex.Unlock() | ||
return | ||
|
||
} | ||
} | ||
}(ctx, h) | ||
} | ||
|
||
// registerConn 注册连接 | ||
func (h *hub) registerConn(conn *Conn) { | ||
select { | ||
case h.register <- conn: | ||
default: | ||
} | ||
} | ||
|
||
// unregisterConn 注销连接 | ||
func (h *hub) unregisterConn(id string) { | ||
select { | ||
case h.unregister <- id: | ||
default: | ||
} | ||
} | ||
|
||
// GetOnlineCount 获取在线人数 | ||
func (h *hub) GetOnlineCount() int { | ||
h.chanMutex.RLock() | ||
defer h.chanMutex.RUnlock() | ||
return h.onlineCount | ||
} | ||
|
||
// GetOnlineBotCount 获取在线机器人数量 | ||
func (h *hub) GetOnlineBotCount() int { | ||
h.chanMutex.RLock() | ||
defer h.chanMutex.RUnlock() | ||
return h.botCount | ||
} | ||
|
||
// IsOnline 是否在线 | ||
func (h *hub) IsOnline(id string) bool { | ||
h.chanMutex.RLock() | ||
_, exist := h.connections[id] | ||
h.chanMutex.RUnlock() | ||
return exist | ||
} | ||
|
||
// GetOnlineAll 获取所有在线连接 | ||
func (h *hub) GetOnlineAll() map[string]*Conn { | ||
h.chanMutex.RLock() | ||
cop := hash.Copy(h.connections) | ||
h.chanMutex.RUnlock() | ||
return cop | ||
} | ||
|
||
// GetOnline 获取在线连接 | ||
func (h *hub) GetOnline(id string) *Conn { | ||
h.chanMutex.RLock() | ||
conn := h.connections[id] | ||
h.chanMutex.RUnlock() | ||
return conn | ||
} | ||
|
||
// CloseConn 关闭连接 | ||
func (h *hub) CloseConn(id string) { | ||
h.chanMutex.RLock() | ||
conn := h.connections[id] | ||
h.chanMutex.RUnlock() | ||
if conn != nil { | ||
conn.Close() | ||
} | ||
} | ||
|
||
// Broadcast 广播消息 | ||
func (h *hub) Broadcast(packet []byte, filter ...func(conn *Conn) bool) { | ||
m := hubBroadcast{ | ||
packet: packet, | ||
} | ||
if len(filter) > 0 { | ||
m.filter = filter[0] | ||
} | ||
select { | ||
case h.broadcast <- m: | ||
default: | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters