63 lines
1.2 KiB
Go
63 lines
1.2 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),
|
|
}
|
|
}
|
|
|
|
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()
|
|
}
|
|
}
|
|
}
|
|
|
|
func (h *ChatHub) Broadcast(message *domain.Message) {
|
|
h.broadcast <- message
|
|
}
|