74 lines
1.6 KiB
Go
74 lines
1.6 KiB
Go
package ws
|
||
|
||
import (
|
||
"sync"
|
||
"tailly_back_v2/internal/domain"
|
||
)
|
||
|
||
type Client struct {
|
||
UserID int
|
||
Send chan *domain.Message
|
||
}
|
||
|
||
type ChatHub struct {
|
||
clients map[int]*Client
|
||
register chan *Client
|
||
unregister chan *Client
|
||
broadcast chan *domain.Message
|
||
mutex sync.RWMutex
|
||
}
|
||
|
||
func NewChatHub() *ChatHub {
|
||
return &ChatHub{
|
||
clients: make(map[int]*Client),
|
||
register: make(chan *Client),
|
||
unregister: make(chan *Client),
|
||
broadcast: make(chan *domain.Message),
|
||
}
|
||
}
|
||
|
||
// Register добавляет нового клиента в хаб
|
||
func (h *ChatHub) Register(client *Client) {
|
||
h.register <- client
|
||
}
|
||
|
||
// Unregister удаляет клиента из хаба
|
||
func (h *ChatHub) Unregister(client *Client) {
|
||
h.unregister <- client
|
||
}
|
||
|
||
// Broadcast отправляет сообщение всем клиентам
|
||
func (h *ChatHub) Broadcast(message *domain.Message) {
|
||
h.broadcast <- message
|
||
}
|
||
|
||
func (h *ChatHub) Run() {
|
||
for {
|
||
select {
|
||
case client := <-h.register:
|
||
h.mutex.Lock()
|
||
h.clients[client.UserID] = client
|
||
h.mutex.Unlock()
|
||
|
||
case client := <-h.unregister:
|
||
h.mutex.Lock()
|
||
if _, ok := h.clients[client.UserID]; ok {
|
||
close(client.Send)
|
||
delete(h.clients, client.UserID)
|
||
}
|
||
h.mutex.Unlock()
|
||
|
||
case message := <-h.broadcast:
|
||
h.mutex.RLock()
|
||
// Отправляем отправителю и получателю
|
||
if sender, ok := h.clients[message.SenderID]; ok {
|
||
sender.Send <- message
|
||
}
|
||
if receiver, ok := h.clients[message.ReceiverID]; ok {
|
||
receiver.Send <- message
|
||
}
|
||
h.mutex.RUnlock()
|
||
}
|
||
}
|
||
}
|