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) } } } } }