118 lines
2.1 KiB
Go
118 lines
2.1 KiB
Go
package websocket
|
||
|
||
import (
|
||
"sync"
|
||
)
|
||
|
||
type Room struct {
|
||
ID int64
|
||
Clients map[*Client]bool
|
||
mu sync.RWMutex
|
||
}
|
||
|
||
func NewRoom(chatID int64) *Room {
|
||
return &Room{
|
||
ID: chatID,
|
||
Clients: make(map[*Client]bool),
|
||
}
|
||
}
|
||
|
||
func (r *Room) AddClient(client *Client) {
|
||
r.mu.Lock()
|
||
defer r.mu.Unlock()
|
||
|
||
r.Clients[client] = true
|
||
client.JoinRoom(r.ID)
|
||
}
|
||
|
||
func (r *Room) RemoveClient(client *Client) {
|
||
r.mu.Lock()
|
||
defer r.mu.Unlock()
|
||
|
||
if _, exists := r.Clients[client]; exists {
|
||
delete(r.Clients, client)
|
||
client.LeaveRoom(r.ID)
|
||
}
|
||
}
|
||
|
||
func (r *Room) Broadcast(message []byte, excludeClient *Client) {
|
||
r.mu.RLock()
|
||
defer r.mu.RUnlock()
|
||
|
||
for client := range r.Clients {
|
||
if excludeClient != nil && client == excludeClient {
|
||
continue
|
||
}
|
||
|
||
// Безопасная отправка с проверкой закрытого канала
|
||
func() {
|
||
defer func() {
|
||
if r := recover(); r != nil {
|
||
// Канал закрыт, игнорируем
|
||
}
|
||
}()
|
||
select {
|
||
case client.send <- message:
|
||
default:
|
||
// Канал заполнен или закрыт
|
||
}
|
||
}()
|
||
}
|
||
}
|
||
|
||
func (r *Room) BroadcastToAll(message []byte) {
|
||
r.Broadcast(message, nil)
|
||
}
|
||
|
||
func (r *Room) GetClientCount() int {
|
||
r.mu.RLock()
|
||
defer r.mu.RUnlock()
|
||
return len(r.Clients)
|
||
}
|
||
|
||
func (r *Room) GetClients() []*Client {
|
||
r.mu.RLock()
|
||
defer r.mu.RUnlock()
|
||
|
||
clients := make([]*Client, 0, len(r.Clients))
|
||
for client := range r.Clients {
|
||
clients = append(clients, client)
|
||
}
|
||
return clients
|
||
}
|
||
|
||
func (r *Room) IsEmpty() bool {
|
||
r.mu.RLock()
|
||
defer r.mu.RUnlock()
|
||
return len(r.Clients) == 0
|
||
}
|
||
|
||
func (r *Room) HasClient(client *Client) bool {
|
||
r.mu.RLock()
|
||
defer r.mu.RUnlock()
|
||
_, exists := r.Clients[client]
|
||
return exists
|
||
}
|
||
|
||
func (r *Room) GetUserIDs() []int64 {
|
||
r.mu.RLock()
|
||
defer r.mu.RUnlock()
|
||
|
||
userIDs := make([]int64, 0, len(r.Clients))
|
||
for client := range r.Clients {
|
||
userIDs = append(userIDs, client.userID)
|
||
}
|
||
return userIDs
|
||
}
|
||
|
||
func (r *Room) HasClientByUserID(userID int64) bool {
|
||
r.mu.RLock()
|
||
defer r.mu.RUnlock()
|
||
|
||
for client := range r.Clients {
|
||
if client.userID == userID {
|
||
return true
|
||
}
|
||
}
|
||
return false
|
||
} |