Initial commit: Эфир мессенджер
This commit is contained in:
118
internal/websocket/room.go
Normal file
118
internal/websocket/room.go
Normal file
@@ -0,0 +1,118 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user