Initial commit: Эфир мессенджер

This commit is contained in:
2026-04-06 14:57:36 +03:00
commit ff93679b6d
50 changed files with 5642 additions and 0 deletions

118
internal/websocket/room.go Normal file
View 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
}