我們的國標GB28181流媒體服務器輸出視頻,有兩種模式進行傳輸:UDP和TCP,UDP的傳輸雖然快,但是容易丟包,TCP的傳輸雖然穩定可靠,但也比較容易佔用資源,用戶可以根據自己的需要來選擇傳輸協議。
一般情況下,我們在發佈國標流媒體服務器的新版本之前,會對版本各個細節的兼容性進行測試,本文依舊是在測試過程中發現的報錯問題。
EasyGBS使用TCP拉流報runtime error
近期在雲平臺服務器上測試發現,EasyGBS在TCP拉流時,運行一段時間後會崩潰的問題,查看日誌,發現報錯:
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x1 addr=0x38 pc=0xaeacc8]
goroutine 13078 [running]:
gitee.com/easydarwin/EasyGBSGo/sms/uas.(*MediaSession).Keepalive(0xc00190a9a0)
D:/Golang/own/src/gitee.com/easydarwin/EasyGBSGo/sms/uas/media_session.go:112 +0x288
created by gitee.com/easydarwin/EasyGBSGo/sms/uas.HandleInvite
D:/Golang/own/src/gitee.com/easydarwin/EasyGBSGo/sms/uas/handle_invite.go:257 +0x15bc
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x1 addr=0x38 pc=0xaeacc8]
經過查看代碼,分析發現,在tcp模式下流保活仍採用的udpserver服務進行保活數據記錄,而此時的udpserver還未開啓,以致指針越界發生未知的錯誤,從而導致程序崩潰。
我們在此做了個流保活數據記錄處理,可成功解決這類問題,代碼如下,供大家參考:
if stream.Cascade != "" {
if msess.MediaTransport == "TCP" {
if msess.RTPTCPServer != nil {
msess.RTPTCPServer.Cascade = stream.Cascade
}
}else {
if msess.RTPUDPServer != nil {
msess.RTPUDPServer.Cascade = stream.Cascade
}
}
}