GB28181信令交互和推流代码实现

一.GB28181信令交互过程

其中,信令1、8、9、10、11、12为SIP服务器接收到客户端的呼叫请求后通过 B2BUA 代理方式建立 媒体流接收者与媒体服务器之间的媒体流信令过程,信令2~7为SIP服务器通过三方呼叫控制建立媒 体服务器与媒体流发送者之间的媒体流信令过程,信令13~16为媒体流接收者断开与媒体服务器之间 的媒体流信令过程,信令17~20为 SIP 服务器断开媒体服务器与媒体流发送者之间的媒体流信令过程。

命令流程描述如下:

1:媒体流接收者向SIP服务器发送Invite消息,消息头域中携带 Subject字段,表明点播的视频源ID、发送方媒体流序列号、媒体流接收者ID、接收端媒体流序列号等参数,SDP消息体中s字段为“Play”代表实时点播。

2:SIP服务器收到Invite请求后,通过三方呼叫控制建立媒体服务器和媒体流发送者之间的媒体连接。向媒体服务器发送Invite消息,此消息不携带SDP消息体。

3:媒体服务器收到SIP服务器的Invite请求后,回复200OK 响应,携带SDP消息体,消息体中描述了媒体服务器接收媒体流的IP、端口、媒体格式等内容。

4:SIP服务器收到媒体服务器返回的200OK 响应后,向媒体流发送者发送Invite请求,请求 中携带消息3中媒体服务器回复的200OK 响应消息体,s字段为“Play”代表实时点播,增加y字段描述SSRC值,f字段描述媒体参数。

5:媒体流发送者收到SIP服务器的Invite请求后,回复200OK 响应,携带SDP消息体,消息体中描述了媒体流发送者发送媒体流的IP、端口、媒体格式、SSRC字段等内容。

6:SIP服务器收到媒体流发送者返回的200OK 响应后,向媒体服务器发送 ACK 请求,请求中携带消息5中媒体流发送者回复的200OK 响应消息体,完成与媒体服务器的Invite会话建立过程。

7:SIP服务器收到媒体流发送者返回的200OK 响应后,向媒体流发送者发送 ACK 请求,请求中不携带消息体,完成与媒体流发送者的Invite会话建立过程。

8:完成三方呼叫控制后,SIP服务器通过B2BUA 代理方式建立媒体流接收者和媒体服务器之间的媒体连接。在消息1中增加SSRC值,转发给媒体服务器。

9:媒体服务器收到Invite请求,回复200OK 响应,携带SDP消息体,消息体中描述了媒体服务器发送媒体流的IP、端口、媒体格式、SSRC值等内容。

10:SIP服务器将消息9转发给媒体流接收者。

11:媒体流接收者收到200OK 响应后,回复 ACK 消息,完成与SIP服务器的Invite会话建立过程。

12:SIP服务器将消息11转发给媒体服务器,完成与媒体服务器的Invite会话建立过程。

13:媒体流接收者向SIP服务器发送 BYE消息,断开消息1、10、11建立的同媒体流接收者的Invite会话。

14:SIP服务器收到 BYE消息后回复200OK 响应,会话断开。

15:SIP服务器收到 BYE消息后向媒体服务器发送 BYE消息,断开消息8、9、12建立的同媒体服务器的Invite会话。

16:媒体服务器收到 BYE消息后回复200OK 响应,会话断开。

17:SIP服务器向媒体服务器发送 BYE 消息,断开消息2、3、6建立的同媒体服务器的Invite会话。

18:媒体服务器收到 BYE消息后回复200OK 响应,会话断开。

19:SIP 服务器向媒体流发送者发送 BYE 消息,断开消息4、5、7建立的同媒体流发送者的Invite会话。

20:媒体流发送者收到 BYE消息后回复200OK 响应,会话断开。

======================================

二.GB28181代码实现:
#include "SipClient.h"
#include "SipServerConfig.h"
#include "Utils/Log.h"
using namespace GB28181;

int main(int argc, char *argv[]) {
    LOGI("GB28181 start!");
  
    const char *serverIp = "192.168.1.224";
    int serverPort = 15060;
    const char *serverSipId = "34020000002000000001";
    const char *serverSipRealm = "3402000000";
    const char *serverSipPass = "123456789";
    int serverSipTimeout = 0;
    int serverSipExpiry = 3600;


    const char *clientUa = "GB28181Client";
    const char *clientIp = "192.168.1.224";
    int clientPort = 5060;
    const char *clientId = "34020000001310000001";
    int localRtpPort = 10001;// 本地RTP的推流端口

    SipServerConfig serverConfig(serverIp,serverPort,serverSipId,serverSipRealm,
                             serverSipPass,serverSipTimeout,serverSipExpiry);
    SipClientConfig clientConfig(clientUa,clientIp,clientPort,clientId,localRtpPort);

    SipClient client(&serverConfig,&clientConfig);
    client.loop();

    return 0;
}

进入main函数后,配置服务器和客户端的数据,然后进入client.loop(),初始化sip服务器,sip服务器eXosip_event_wait开始等待接收客户端的请求等。sip服务器初始化流程如下:

1)eXosip_init                            (初始化)             
2)eXosip_listen_addr                     (监听sip端口)    
3)eXosip_register_build_initial_register (构建一个register)
4)eXosip_register_send_register          (发送register)
5)eXosip_event_wait                      (等待对端事件)
6)eXosip_execute                         (处理事件,调整内部状态)
7)eXosip_automatic_action                (根据当前状况,发出响应消息)

client.loop()循环接受客户端sip请求事件

根据时间类型执行不同请求:

例如客户端发起Invite推流请求

进入response_invite,对客户端的invite请求做出回应,以及发送解析的sdp消息结构体等

接收到信令服务器的ask后,后开始推流

RtpSendPs实例化一个对象,进行创建udp端连接,非阻塞监听mSockFd套接字,为推流做准备。

建立udp连接后,start创建推流线程SendDataThread,开始音视频流推送服务,gb28181_streampackageForH264主要进行码流分包封装任务和包头结构封装任务,最后进行打包发送。

### GB28181信令交互中481500错误解决方案 #### 一、错误码481分析与解决方法 错误码`481 Call/Transaction Does Not Exist`表示呼叫或事务不存在。这通常发生在请求尝试操作一个已经终止或从未存在的对话时。 对于GB/T 28181标准下的SIP通信而言,当接收到此响应时意味着服务器未能找到对应的INVITE交易记录[^1]。具体应对措施如下: - **确认消息序列号**:确保客户端发送的消息序号(CSeq)正确无误,并且每次重发都保持一致。 - **检查分支参数**:验证vias头部内的branch参数是否匹配原始邀请请求中的值;如果不符,则可能是由于代理节点转发过程中出现了问题所致。 - **审查注册状态**:如果设备频繁遭遇此类报错,需排查其在网络内登记的状态是否正常有效,防止因认证失败而导致后续动作无法执行成功。 ```python def check_sip_message(message): """ 检查SIP消息的关键字段以预防481错误 参数: message (str): SIP消息字符串 返回: bool: 是否通过校验 """ try: cseq_line = next((line for line in message.split('\r\n') if 'CSeq' in line)) via_branches = re.findall(r';branch=([^;]+)', message) # 进一步逻辑判断... return True except StopIteration as e: print(f"SIP Message Format Error: {e}") return False ``` #### 二、错误码500分析与解决办法 错误码`500 Server Internal Error`表明服务端遇到了内部异常情况而不能完成处理过程。这类问题往往难以定位确切原因,因为它们可以由多种因素引起,比如资源耗尽、程序缺陷或是配置不当等。 针对GB/T 28181应用场景里的这种情况,建议采取以下策略来诊断并修复潜在隐患: - **日志审计**:收集来自各个组件的日志文件,特别是涉及媒体网关控制器(MGC)服务质量(QoS)监控系统的记录条目,从中寻找线索指向具体的故障源头。 - **性能优化**:评估当前部署架构能否满足预期负载需求,必要时调整硬件资源配置或者改进软件算法效率,减少不必要的计算开销。 - **版本兼容性测试**:考虑到不同厂商的产品可能存在差异化的实现细节,在升级固件之前务必进行全面的功能性互操作性的回归测试工作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

肖爱Kun

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值