package handlers import ( "context" "net/http" "tailly_back_v2/internal/domain" "tailly_back_v2/internal/service" "tailly_back_v2/internal/ws" "tailly_back_v2/pkg/auth" "github.com/gorilla/websocket" ) var upgrader = websocket.Upgrader{ ReadBufferSize: 1024, WriteBufferSize: 1024, CheckOrigin: func(r *http.Request) bool { return true // В production заменить на проверку origin }, } type ChatHandler struct { chatService service.ChatService hub *ws.Hub tokenAuth *auth.TokenAuth } func NewChatHandler(chatService service.ChatService, hub *ws.Hub, tokenAuth *auth.TokenAuth) *ChatHandler { return &ChatHandler{ chatService: chatService, hub: hub, tokenAuth: tokenAuth, } } func (h *ChatHandler) HandleWebSocket(w http.ResponseWriter, r *http.Request) { // Аутентификация пользователя token := r.URL.Query().Get("token") if token == "" { http.Error(w, "Token is required", http.StatusUnauthorized) return } userID, err := h.tokenAuth.ValidateAccessToken(token) if err != nil { http.Error(w, "Invalid token", http.StatusUnauthorized) return } conn, err := upgrader.Upgrade(w, r, nil) if err != nil { http.Error(w, "Could not open websocket connection", http.StatusBadRequest) return } client := &ws.Client{ UserID: userID, Send: make(chan *domain.Message, 256), } h.hub.RegisterClient(client) // Горутина для чтения сообщений go h.readPump(conn, client, userID) // Горутина для записи сообщений go h.writePump(conn, client) } func (h *ChatHandler) readPump(conn *websocket.Conn, client *ws.Client, userID int) { defer func() { h.hub.UnregisterClient(client) conn.Close() }() for { var msg struct { ChatID int `json:"chatId"` Content string `json:"content"` } if err := conn.ReadJSON(&msg); err != nil { break } // Используем context.Background() вместо r.Context() message, err := h.chatService.SendMessage( context.Background(), userID, msg.ChatID, msg.Content, ) if err != nil { continue } h.hub.Broadcast(message) } } func (h *ChatHandler) writePump(conn *websocket.Conn, client *ws.Client) { defer conn.Close() for message := range client.Send { if err := conn.WriteJSON(message); err != nil { break } } }