EasyCVR作为视频协议融合平台,除了支持RTSP、GB28181等大众协议外,还支持海康SDK、大华SDK等私有协议,如今我们也支持了阿里的上云协议。
在开发EasyCVR对接阿里上云协议的时候,我们发现上传通道数据库一直不显示问题。此时上传代码如下,首先在数据库查询符合条件的通道,然后将通道按照对应的数据结构写入websocket长链接。
err = database.Table(cvrdo.DBChannelInfo{}.TableName()).Order("channel_id").Where("protocol=?", "GB").Find(&dbChannels).Error
if err != nil {
log.Printf("channels err,%s", err.Error())
return
}
var channels = []values.ValueMap{}
//初始化默认通道
channels = append(channels, values.ValueMap{
"cid": 0,
"name": "",
"status": 1, //0 位置状态 1在线 2 异常 3 离线
"protocols": []string{"GB/T-28181-E"}, //ONVIF-E GB/T-28181-E ODCAP gb28181-e
"capability": values.ValueMap{
"live": values.ValueMap{
"pushProtocols": []string{"rtmp"},
},
//"ptz": values.ValueMap{
// "pan": "on",
//},
},
})
但是此时上级数据库中是没有数据的,显示如下:
通过抓包和阿里官方例子对比数据,我们发现问题出现的原因是上传的请求头消息少了4位。以下为本地上传的抓包数据:
阿里demo上传数据:
通过对比能够查看出data数据头文件少了4位,因此我们修改代码如下:
channebyte, err := json.Marshal(channeArr)
if err != nil {
log.Printf("channebyte, err := json.Marshal(channeArr) err, %s", err.Error())
return
}
content := fmt.Sprintf("POST /v1/odcap/channels HTTP/1.1
Host:
User-Agent: Go-http-client/1.1
Content-Length: %d
Content-Type: application/json;
", len(channebyte))
bytearr := make([]byte, 12)
bytearr[0] = 1
binary.BigEndian.PutUint16(bytearr[1:], uint16(1))
bytearr[3] = 1 //0 消息无需应答 1请求 2应答
binary.BigEndian.PutUint32(bytearr[4:], cseqGetValue()) //cseq 每次请求递增
bytearr = append(bytearr, []byte(content)...)
bytearr = append(bytearr, channebyte...)
writeResponse(bytearr)
再次抓包查看数据,数据包显示正常。
此时查看数据库文件,设备通道也正常注册上去了,该问题得以解决。