sendMessage sends a message to the WebSocket client
(wsConn *WebSocketConnection, msgType string, payload map[string]any)
| 435 | |
| 436 | // sendMessage sends a message to the WebSocket client |
| 437 | func (h *WebSocketHandler) sendMessage(wsConn *WebSocketConnection, msgType string, payload map[string]any) { |
| 438 | // 检查 context 是否已取消 |
| 439 | if wsConn.ctx.Err() != nil { |
| 440 | return |
| 441 | } |
| 442 | |
| 443 | msg := WebSocketMessage{ |
| 444 | Type: msgType, |
| 445 | Payload: payload, |
| 446 | } |
| 447 | |
| 448 | data, err := json.Marshal(msg) |
| 449 | if err != nil { |
| 450 | logging.Error(wsConn.ctx, "websocket.marshal.error", map[string]any{ |
| 451 | "error": err.Error(), |
| 452 | }) |
| 453 | return |
| 454 | } |
| 455 | |
| 456 | // 使用 defer recover 防止发送到已关闭的 channel 导致 panic |
| 457 | defer func() { |
| 458 | if r := recover(); r != nil { |
| 459 | logging.Warn(wsConn.ctx, "websocket.send.recovered", map[string]any{ |
| 460 | "connection_id": wsConn.ID, |
| 461 | "message_type": msgType, |
| 462 | "panic": r, |
| 463 | }) |
| 464 | } |
| 465 | }() |
| 466 | |
| 467 | select { |
| 468 | case wsConn.Send <- data: |
| 469 | case <-wsConn.ctx.Done(): |
| 470 | default: |
| 471 | // Channel full, skip message |
| 472 | logging.Warn(wsConn.ctx, "websocket.send.dropped", map[string]any{ |
| 473 | "connection_id": wsConn.ID, |
| 474 | "message_type": msgType, |
| 475 | }) |
| 476 | } |
| 477 | } |
| 478 | |
| 479 | // sendError sends an error message to the WebSocket client |
| 480 | func (h *WebSocketHandler) sendError(wsConn *WebSocketConnection, code, message string) { |
no test coverage detected