fonchain-fiee/pkg/service/websocket/server/client_manager.go
2025-02-19 14:24:15 +08:00

211 lines
5.1 KiB
Go

package server
import (
"fmt"
"sync"
)
type ClientManager struct {
Clients map[*Client]bool // 全部的连接
ClientsLock sync.RWMutex // 读写锁
Users map[string]*Client // 登录的用户 // appID+uuid
UserLock sync.RWMutex // 读写锁
Register chan *Client // 连接连接处理
Login chan *login // 用户登录处理
Unregister chan *Client // 断开连接处理程序
Broadcast chan []byte // 广播 向全部成员发送数据
}
// 用户登录
type login struct {
UserID string
Client *Client
}
func NewClientManager() (clientManager *ClientManager) {
clientManager = &ClientManager{
Clients: make(map[*Client]bool),
Users: make(map[string]*Client),
Register: make(chan *Client, 1000),
Login: make(chan *login, 1000),
Unregister: make(chan *Client, 1000),
Broadcast: make(chan []byte, 1000),
}
return
}
// EventRegister 用户建立连接事件
func (manager *ClientManager) EventRegister(client *Client) {
manager.AddClients(client)
// client.Send <- []byte("连接成功")
}
// AddClients 添加客户端
func (manager *ClientManager) AddClients(client *Client) {
manager.ClientsLock.Lock()
defer manager.ClientsLock.Unlock()
manager.Clients[client] = true
}
// EventLogin 用户登录
func (manager *ClientManager) EventLogin(login *login) {
client := login.Client
// 连接存在,在添加
if manager.InClient(client) {
var userKey string = login.UserID
manager.AddUsers(userKey, login.Client)
}
}
// AddUsers 添加用户
func (manager *ClientManager) AddUsers(key string, client *Client) {
manager.UserLock.Lock()
defer manager.UserLock.Unlock()
manager.Users[key] = client
}
func (manager *ClientManager) InClient(client *Client) (ok bool) {
manager.ClientsLock.RLock()
defer manager.ClientsLock.RUnlock()
// 连接存在,在添加
_, ok = manager.Clients[client]
return
}
// DelClients 删除客户端
func (manager *ClientManager) DelClients(client *Client) {
manager.ClientsLock.Lock()
defer manager.ClientsLock.Unlock()
if _, ok := manager.Clients[client]; ok {
delete(manager.Clients, client)
}
}
func (manager *ClientManager) GetUserClient(userID string) (client *Client) {
manager.UserLock.RLock()
defer manager.UserLock.RUnlock()
userKey := GetUserKey(userID)
if value, ok := manager.Users[userKey]; ok {
client = value
}
return
}
// GetUserKeys 获取用户的key
func (manager *ClientManager) GetUserKeys() (userKeys []string) {
userKeys = make([]string, 0, len(manager.Users))
for key := range manager.Users {
userKeys = append(userKeys, key)
}
return
}
func (manager *ClientManager) GetUsersLen() (userLen int) {
userLen = len(manager.Users)
return
}
// GetUserKey 获取用户key
func GetUserKey(userID string) (key string) {
key = fmt.Sprintf("%s", userID)
return
}
// DelUsers 删除用户
func (manager *ClientManager) DelUsers(client *Client) (result bool) {
manager.UserLock.Lock()
defer manager.UserLock.Unlock()
key := GetUserKey(client.UserID)
if value, ok := manager.Users[key]; ok {
// 判断是否为相同的用户
if value.Addr != client.Addr {
return
}
delete(manager.Users, key)
result = true
}
return
}
// EventUnregister 用户断开连接
func (manager *ClientManager) EventUnregister(client *Client) {
manager.DelClients(client)
// 删除用户连接
deleteResult := manager.DelUsers(client)
if deleteResult == false {
// 不是当前连接的客户端
return
}
//// 清除redis登录数据
//userOnline, err := cache.GetUserOnlineInfo(client.GetKey())
//if err == nil {
// userOnline.LogOut()
// _ = cache.SetUserOnlineInfo(client.GetKey(), userOnline)
//}
// 关闭 chan
// close(client.Send)
fmt.Println("EventUnregister 用户断开连接", client.Addr, client.AppID, client.UserID)
if client.UserID != "" {
fmt.Println("EventUnregister 用户断开连接", client.Addr, client.AppID, client.UserID)
}
}
// ClientsRange 遍历
func (manager *ClientManager) ClientsRange(f func(client *Client, value bool) (result bool)) {
manager.ClientsLock.RLock()
defer manager.ClientsLock.RUnlock()
for key, value := range manager.Clients {
result := f(key, value)
if result == false {
return
}
}
return
}
func (manager *ClientManager) GetClientsLen() (clientsLen int) {
clientsLen = len(manager.Clients)
return
}
// GetClients 获取所有客户端
func (manager *ClientManager) GetClients() (clients map[*Client]bool) {
clients = make(map[*Client]bool)
manager.ClientsRange(func(client *Client, value bool) (result bool) {
clients[client] = value
return true
})
return
}
// 管道处理程序
func (manager *ClientManager) Start() {
for {
select {
case conn := <-manager.Register:
// 建立连接事件
manager.EventRegister(conn)
case l := <-manager.Login:
// 用户登录
manager.EventLogin(l)
case conn := <-manager.Unregister:
// 断开连接事件
manager.EventUnregister(conn)
case message := <-manager.Broadcast:
// 广播事件
clients := manager.GetClients()
for conn := range clients {
select {
case conn.Send <- message:
default:
close(conn.Send)
}
}
}
}
}