From e499729c5893be1f9b88ec0d2ad925c95ba2d3ae Mon Sep 17 00:00:00 2001 From: Eli Yip Date: Thu, 29 May 2025 10:52:40 +0800 Subject: [PATCH] chore: add timeout for can communicator --- communication/communicator.go | 15 ++++++++++++--- device/models/l10.go | 7 ++++++- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/communication/communicator.go b/communication/communicator.go index 41d2323..978840d 100644 --- a/communication/communicator.go +++ b/communication/communicator.go @@ -2,6 +2,7 @@ package communication import ( "bytes" + "context" "encoding/json" "fmt" "io" @@ -20,7 +21,7 @@ type RawMessage struct { // Communicator 定义了与 can-bridge Web 服务进行通信的接口 type Communicator interface { // SendMessage 将 RawMessage 通过 HTTP POST 请求发送到 can-bridge 服务 - SendMessage(msg RawMessage) error + SendMessage(ctx context.Context, msg RawMessage) error // GetInterfaceStatus 获取指定 CAN 接口的状态 GetInterfaceStatus(ifName string) (isActive bool, err error) @@ -50,14 +51,22 @@ func NewCanBridgeClient(serviceURL string) Communicator { } } -func (c *CanBridgeClient) SendMessage(msg RawMessage) error { +func (c *CanBridgeClient) SendMessage(ctx context.Context, msg RawMessage) error { jsonData, err := json.Marshal(msg) if err != nil { return fmt.Errorf("序列化消息失败:%w", err) } url := fmt.Sprintf("%s/api/can", c.serviceURL) - resp, err := c.client.Post(url, "application/json", bytes.NewBuffer(jsonData)) + + // 创建带有 context 的请求 + req, err := http.NewRequestWithContext(ctx, "POST", url, bytes.NewBuffer(jsonData)) + if err != nil { + return fmt.Errorf("创建 HTTP 请求失败:%w", err) + } + req.Header.Set("Content-Type", "application/json") + + resp, err := c.client.Do(req) if err != nil { return fmt.Errorf("发送 HTTP 请求失败:%w", err) } diff --git a/device/models/l10.go b/device/models/l10.go index 3da54d9..221853e 100644 --- a/device/models/l10.go +++ b/device/models/l10.go @@ -1,6 +1,7 @@ package models import ( + "context" "fmt" "log" "math/rand/v2" @@ -245,8 +246,12 @@ func (h *L10Hand) ExecuteCommand(cmd device.Command) error { return fmt.Errorf("转换指令失败:%w", err) } + // 创建带有超时的 context,设置 3 秒超时 + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + // 发送到 can-bridge 服务 - if err := h.communicator.SendMessage(rawMsg); err != nil { + if err := h.communicator.SendMessage(ctx, rawMsg); err != nil { h.status.ErrorCount++ h.status.LastError = err.Error() log.Printf("❌ %s (%s) 发送指令失败: %v (ID: 0x%X, Data: %X)", h.id, h.handType.String(), err, rawMsg.ID, rawMsg.Data)