如何为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格式事件数据) - 认证复用:沿用原有快照代码的摘要认证逻辑,完美适配大华相机的权限验证机制
注意事项
- 大华相机推送的事件多为XML格式,可在
handleEvent中添加XML解析逻辑,提取事件类型、时间、通道号等关键信息 - 可根据实际场景调整
reconnectGap重试间隔,避免频繁重试给相机造成压力 - 若需要监听多种事件,可修改
eventURI中的codes参数,例如codes=[VideoMotion,AlarmLocal] - 生产环境建议添加日志持久化、监控告警等逻辑,提升服务稳定性
内容的提问来源于stack exchange,提问作者Venkata Subbarao
相关产品推荐
相关产品推荐

