You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为net/http GET请求设置读取回调(适配MIPS架构,大华相机场景)

大华相机事件推送长连接的Go实现方案

我们现有一个可从大华相机获取快照的Go程序,需要对接URI http://192.168.x.x/cgi-bin/eventManager.cgi?action=attach&codes=[VideoMotion]——这个URI会建立长Socket连接,相机通过该连接持续推送移动侦测事件。之前尝试过支持读取回调的go-curl,但该包不支持MIPS架构无法使用,因此基于现有快照代码改造出兼容方案。

现有快照获取代码

package main

import (
       "fmt"
    "log"
    "net/http"

    "github.com/icholy/digest"
)

const (
    username = "xxxxx"
    password = "xxxxx"
    uri = "http://192.168.x.x/cgi-bin/snapshot.cgi"
)

func main() {
    client := &http.Client{
        Transport: &digest.Transport{
            Username: username,
            Password: password,
        },
    }

    resp, err := client.Get(uri)
    if err != nil {
        log.Fatal(err)
    }
    defer resp.Body.Close()

    if resp.StatusCode != http.StatusOK {
        log.Fatalf("Error: Status code %d", resp.StatusCode)
    } else {
        fmt.Println("Snapshot fetched")
    }

    // Perform next steps
}

改造后的事件监听实现

以下是基于Go标准库的长连接事件监听代码,兼容MIPS架构,包含事件读取回调逻辑:

package main

import (
    "bufio"
    "fmt"
    "log"
    "net/http"
    "time"

    "github.com/icholy/digest"
)

const (
    username     = "xxxxx"
    password     = "xxxxx"
    eventURI     = "http://192.168.x.x/cgi-bin/eventManager.cgi?action=attach&codes=[VideoMotion]"
    reconnectGap = 5 * time.Second // 连接断开后重试间隔
)

// 事件处理回调函数,可根据业务需求自定义逻辑
func handleEvent(data string) {
    fmt.Printf("收到事件: %s\n", data)
    // 示例:触发快照获取、记录告警日志、推送通知等
}

// 建立事件长连接并持续监听
func startEventListener(client *http.Client) {
    for {
        resp, err := client.Get(eventURI)
        if err != nil {
            log.Printf("连接事件接口失败: %v,%v后重试", err, reconnectGap)
            time.Sleep(reconnectGap)
            continue
        }

        if resp.StatusCode != http.StatusOK {
            log.Printf("事件接口返回错误状态码: %d,%v后重试", resp.StatusCode, reconnectGap)
            resp.Body.Close()
            time.Sleep(reconnectGap)
            continue
        }

        log.Println("已建立事件推送长连接,开始监听移动侦测事件")

        // 按行读取相机推送的事件数据(大华相机通常以行分隔事件)
        scanner := bufio.NewScanner(resp.Body)
        for scanner.Scan() {
            eventData := scanner.Text()
            if eventData != "" {
                handleEvent(eventData)
            }
        }

        // 连接断开或读取出错时的处理
        if err := scanner.Err(); err != nil {
            log.Printf("读取事件数据出错: %v", err)
        } else {
            log.Println("事件推送连接已断开")
        }

        resp.Body.Close()
        log.Printf("%v后尝试重新连接", reconnectGap)
        time.Sleep(reconnectGap)
    }
}

func main() {
    // 初始化带摘要认证的HTTP客户端,禁用超时以支持长连接
    client := &http.Client{
        Transport: &digest.Transport{
            Username: username,
            Password: password,
        },
        Timeout: 0,
    }

    // 启动事件监听协程,不阻塞主协程
    go startEventListener(client)

    // 主协程保持运行,可在此添加其他业务逻辑(如快照定时获取、API服务等)
    select {}
}

关键说明

  • MIPS架构兼容:完全使用Go标准库和纯Go实现的digest认证包,无C语言依赖,可直接在MIPS平台编译运行
  • 长连接稳定性:内置自动重连逻辑,连接断开后按设定间隔重试,保证事件监听不中断
  • 回调扩展性:handleEvent函数作为事件处理入口,可灵活添加业务逻辑(如触发快照、发送告警通知等)
  • 数据适配:使用bufio.Scanner按行读取,适配大华相机默认的事件推送格式(每行一条XML格式事件数据)
  • 认证复用:沿用原有快照代码的摘要认证逻辑,完美适配大华相机的权限验证机制

注意事项

  1. 大华相机推送的事件多为XML格式,可在handleEvent中添加XML解析逻辑,提取事件类型、时间、通道号等关键信息
  2. 可根据实际场景调整reconnectGap重试间隔,避免频繁重试给相机造成压力
  3. 若需要监听多种事件,可修改eventURI中的codes参数,例如codes=[VideoMotion,AlarmLocal]
  4. 生产环境建议添加日志持久化、监控告警等逻辑,提升服务稳定性

内容的提问来源于stack exchange,提问作者Venkata Subbarao

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 10:25:32