很多情况下我们常用的协议是http协议,但是http存在一个明显的缺点:通信只能由客户端发起,所以在编译视频综合管理平台这类项目时,当涉及到服务端与客户端的双向通信时,就需要通过另一种协议来实现,即websocket协议。websocket协议下,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话。
在我们采用EasyCVR安防监控智能分析系统对接第三方平台时,当通过websocket长连接和三方平台建立连接,此时突然断网,或者是三方服务崩溃重启,也就是说连接突然中断后,会导致建立的websocket链接无法再次实现重连,程序消息一直被阻塞住。
程序启动时,打印的链接状态如下:
第三方服务端处于请求状态:
当服务端重启或断链之后,客户端出现崩溃,程序阻塞的情况:
此时客户端代码建立连接代码如下:
代码语言:javascript复制//ping
upaliServer.ping()
writeFunc := func(params []byte) {
upaliServer.WriteMessage(websocket.BinaryMessage, params)
}
cseqFunc := func() uint32 {
return RequestCstq.getValue()
}
//初始化api
messapi.Init(writeFunc, cseqFunc)
这段代码实际还是不够完善的,因此此处我们首先定义链接url,再建立连接过后启动ping监听方法,随后再链接断掉之后循环尝试和服务端建立连接,如果失败,则等待一段时间后再次尝试,成功之后退出尝试建立连接的进程。
代码语言:javascript复制log.Printf("connecting to %s", s.url.String())
wsktDlr := websocket.Dialer{TLSClientConfig: &tls.Config{RootCAs: nil, InsecureSkipVerify: true}}
c, hrsp, err := wsktDlr.Dial(s.url.String(), nil)
if err != nil {
log.Printf("dial err %s", err.Error())
time.Sleep(time.Second * 10)
continue
}
if hrsp == nil && hrsp.StatusCode != 200 {
log.Printf("dial hrsp %v", hrsp)
time.Sleep(time.Second)
continue
}
s.client = c
s.connected = true
再次测试当服务器断线之后,客户端能够看到在尝试重连。
当服务端重启之后,客户端能够快速的链接上去,此时该问题就已经解决了。