GB28181学习(十三)——订阅与通知

news2024/9/24 21:17:08

事件订阅

要求

  • 事件订阅应使用SUBSCRIBE方法;
  • 事件源接收事件订阅时,事件源应向事件观察者发送确认消息;
  • 事件源:
    • 联网系统
    • SIP服务器
    • 报警设备
    • 移动设备
    • 被集成的卡口系统等
  • 事件观察者
    • 联网系统
    • SIP服务器
    • 客户端
  • 事件:
    • 报警事件
    • 移动设备位置通知事件
    • PTZ精准位置变化事件等

流程

在这里插入图片描述

协议接口

  • MESSAGE消息头Content-type头域为Content-type:Application/MANSCDP+xml
  • 报警事件订阅流程中请求命令消息体采用MANSCDP协议格式定义:请求命令消息体采用XML封装;
  • 移动位置上报事件订阅流程中请求命令消息体采用MANSCDP协议格式定义:请求命令消息体采用XML封装;
  • PTZ精准位置变化事件订阅流程中请求命令消息体采用MANSCDP协议格式定义:请求命令消息体采用XML封装;

事件通知

要求

  • 事件源接受事件订阅后,在事件触发后应立即通知事件观察者,事件观察者应向事件源发送事件收到的确认消息;
  • 事件通知使用NOTIFY方法;
  • 事件源:
    • 联网系统
    • SIP服务器
    • 报警设备
    • 移动设备
    • 被集成的卡口系统等
  • 事件观察者
    • 联网系统
    • SIP服务器
    • 客户端
  • 事件
    • 报警事件
    • 移动设备位置通知事件
    • PTZ精准位置变化事件等

流程

在这里插入图片描述

协议接口

  • MESSAGE消息头Content-type头域为Content-type:Application/MANSCDP+xml
  • 报警事件订阅流程中请求命令消息体采用MANSCDP协议格式定义:请求命令消息体采用XML封装;
  • 移动位置上报事件订阅流程中请求命令消息体采用MANSCDP协议格式定义:请求命令消息体采用XML封装;
  • PTZ精准位置变化事件订阅流程中请求命令消息体采用MANSCDP协议格式定义:请求命令消息体采用XML封装;

目录订阅

要求

  • 目录订阅应使用SUBSCRIBE方法;
  • 目录拥有者接收目录订阅后,应向目录订阅者发送请求确认消息;
  • 目录拥有者
    • 联网系统
    • 有子设备的设备
    • 代理设备网关
  • 目录接收者
    • 联网系统
    • 有子设备的设备
    • 代理设备网关

流程

在这里插入图片描述

协议接口

  • MESSAGE消息头Content-type头域为Content-type:Application/MANSCDP+xml
  • 目录订阅订阅流程中请求命令消息体采用MANSCDP协议格式定义:请求命令消息体采用XML封装;

目录通知

要求

  • 目录拥有者接收目录订阅后,当目录发生变化时立即通知目录接收者,目录接收者应向目录拥有者发送目录收到的确认消息;
  • 目录通知应使用NOTIFY方法;
  • 目录拥有者
    • 联网系统
    • 有子设备的设备
    • 代理设备网关
  • 目录接收者
    • 联网系统
    • 有子设备的设备
    • 代理设备网关
  • 域间目录订阅通知

流程

在这里插入图片描述

协议接口

  • MESSAGE消息头Content-type头域为Content-type:Application/MANSCDP+xml
  • 目录订阅订阅流程中请求命令消息体采用MANSCDP协议格式定义:请求命令消息体采用XML封装;

代码实现

  • 订阅初始化
pj_init();
pjlib_util_init();
pj_caching_pool_init(&m_cachingPool, &pj_pool_factory_default_policy, 0);
pjsip_endpt_create(&m_cachingPool.factory, nullptr, &m_endPoint);
pjsip_tsx_layer_init_module(m_endPoint);
pjsip_ua_init_module(m_endPoint, nullptr);

// 订阅相关
pjsip_evsub_init_module(m_endPoint);
pjsip_pres_init_module(m_endPoint, pjsip_evsub_instance());
  • 创建报警订阅请求
std::string CMySipMedia::CreateAlarmXmlText_(const std::string& eventName, const GBSubscribeContext& subContext)
{
	char szAlarmInfo[500] = { 0 };
	pj_ansi_snprintf(szAlarmInfo, 500,
		"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
		"<Query>\n"
		"<CmdType>%s</CmdType>\n"
		"<SN>130</SN>\n"
		"<DeviceID>%s</DeviceID>\n"
		"<StartAlarmPrority>0</StartAlarmPrority>\n"
		"<EndAlarmPrority>0</EndAlarmPrority>\n"
		"<AlarmMethod>0</AlarmMethod>\n"
		"<StartTime>%s</StartTime>\n"
		"<EndTime>%s</EndTime>\n"
		"</Query>\n", eventName.c_str()
		, subContext.GetDeviceId().c_str()
		, subContext.GetSubStartTime().c_str()
		, subContext.GetSubEndTime().c_str()
	);

	return szAlarmInfo;
}
  • 订阅
static pjsip_evsub_user pres_user = {
    &pres_on_evsub_state,
    &pres_on_evsub_tsx_state,
    &pres_on_evsub_rx_refresh,
    &pres_on_evsub_rx_notify,
    &pres_on_evsub_client_refresh,
    &pres_on_evsub_server_timeout,
};

// 接收NOTIFY消息
static void pres_on_evsub_rx_notify(pjsip_evsub* sub,
	pjsip_rx_data* rdata,
	int* p_st_code,
	pj_str_t** p_st_text,
	pjsip_hdr* res_hdr,
	pjsip_msg_body** p_body)
{
}

bool CMySipContext::Subscribe(pjsip_dialog* dlg, pjsip_evsub_user* pres_user, const std::string& eventName, const std::string& xmlText, const GBSubscribeContext& subContext)
{
    // 创建uac
	pjsip_evsub* sub = nullptr;
	static const pj_str_t STR_PRESENCE = { (char*)"presence", 8 };
	pj_status_t status = pjsip_evsub_create_uac(dlg, pres_user, &STR_PRESENCE, 0, &sub);
	if (PJ_SUCCESS != status)
		return false;

    // 初始化
	pjsip_tx_data* tdata = nullptr;
	status = pjsip_evsub_initiate(sub, nullptr, subContext.GetExpires(), &tdata);
	if (PJ_SUCCESS != status)
		return false;

    // 构造Body
	pjsip_media_type type;
	type.type = pj_str((char*)"application");
	type.subtype = pj_str((char*)"MANSCDP+xml");
	auto text = pj_str(const_cast<char*>(xmlText.c_str()));
	tdata->msg->body = pjsip_msg_body_create(m_pool, &type.type, &type.subtype, &text);

	auto hName = pj_str((char*)"Subject");
	auto subjectUrl = subContext.GetDeviceId() + ":" + SiralNum + "," + GetCode() + ":" + SiralNum;
	auto hValue = pj_str(const_cast<char*>(subjectUrl.c_str()));
	auto hdr = pjsip_generic_string_hdr_create(m_pool, &hName, &hValue);
	pjsip_msg_add_hdr(tdata->msg, reinterpret_cast<pjsip_hdr*>(hdr));

    // 消息发送
	status = pjsip_evsub_send_request(sub, tdata);
	if (PJ_SUCCESS != status)
		return false;

	return true;
}

抓包

  1. 报警订阅
SUBSCRIBE sip:xxx@192.168.0.111:5060 SIP/2.0
Via: SIP/2.0/UDP 192.168.0.107:5060;rport;branch=xxx
Max-Forwards: 70
From: sip:xxx@192.168.0.107;tag=xxx
To: sip:xxx@192.168.0.111
Contact: <sip:xxx@192.168.0.107:5060>
Call-ID: xxx
CSeq: 18467 SUBSCRIBE
Event: presence;id=xxx
Expires: 300
Supported: 100rel
Accept: application/pidf+xml, application/xpidf+xml
Allow-Events: presence
Subject: xxx:xxx,xxx:xxx
Content-Type: application/MANSCDP+xml
Content-Length:   327

<?xml version="1.0" encoding="UTF-8"?>
<Query>
<CmdType>Alarm</CmdType>
<SN>130</SN>
<DeviceID>xxx</DeviceID>
<StartAlarmPrority>0</StartAlarmPrority>
<EndAlarmPrority>0</EndAlarmPrority>
<AlarmMethod>0</AlarmMethod>
<StartTime>2023-10-24T00:00:00</StartTime>
<EndTime>2023-10-24T23:00:00</EndTime>
</Query>
  1. 报警订阅结果
SIP/2.0 200 OK
Call-ID: xxx
Contact: <sip:xxx@192.168.0.111:5060>
Content-Length: 0
CSeq: 18467 SUBSCRIBE
Event: presence;id=xxx
Expires: 300
From: <sip:xxx@192.168.0.107>;tag=xxx
To: <sip:xxx@192.168.0.111>;tag=xxx
User-Agent: SIP UAS V.2016.xxxx
Via: SIP/2.0/UDP 192.168.0.107:5060;rport=5060;branch=xxx
  1. 报警通知
NOTIFY sip:xxx@192.168.0.107:5060 SIP/2.0
Call-ID: xxx
Contact: <sip:xxx@192.168.0.111:5060>
Content-Length: 416
Content-Type: Application/MANSCDP+xml
CSeq: 2 NOTIFY
Event: presence;id=xxx
From: <sip:xxx@192.168.0.111>;tag=xxx
Max-Forwards: 70
Subscription-State: active;expires=294
To: <sip:xxx@192.168.0.107>;tag=xxx
User-Agent: SIP UAS V.2016.xxxx
Via: SIP/2.0/UDP 192.168.0.111:5060;rport;branch=xxx

<?xml version="1.0" encoding="GB2312" standalone="yes" ?>
<Notify>
<CmdType>Alarm</CmdType>
<SN>29</SN>
<DeviceID>xxx</DeviceID>
<AlarmPriority>1</AlarmPriority>
<AlarmMethod>5</AlarmMethod>
<AlarmTime>2023-10-24T10:17:45</AlarmTime>
<AlarmDescription>........</AlarmDescription>
<AlarmInfo>11</AlarmInfo>
<Info>
<AlarmType>2</AlarmType>
<AlarmTypeParam>
<EventType>1</EventType>
</AlarmTypeParam>
</Info>
</Notify>
  1. 报警通知返回
SIP/2.0 200 OK
Via: SIP/2.0/UDP 192.168.0.111:5060;rport=5060;received=192.168.0.111;branch=xxx
Call-ID: xxx
From: <sip:xxx@192.168.0.111>;tag=xxx
To: <sip:xxx@192.168.0.107>;tag=xxx
CSeq: 2 NOTIFY
Content-Length:  0
  1. 取消订阅
SUBSCRIBE sip:xxx@192.168.0.111:5060 SIP/2.0
Via: SIP/2.0/UDP 192.168.0.107:5060;rport;branch=xxx
Max-Forwards: 70
From: sip:xxx@192.168.0.107;tag=xxx
To: sip:xxx@192.168.0.111
Contact: <sip:xxx@192.168.0.107:5060>
Call-ID: xxx
CSeq: 26500 SUBSCRIBE
Event: presence;id=xxx
Expires: 0
Supported: 100rel
Accept: application/pidf+xml, application/xpidf+xml
Allow-Events: presence
Subject: xxx:xx,xxx:xx
Content-Type: application/MANSCDP+xml
Content-Length:   327

<?xml version="1.0" encoding="UTF-8"?>
<Query>
<CmdType>Alarm</CmdType>
<SN>130</SN>
<DeviceID>xxx</DeviceID>
<StartAlarmPrority>0</StartAlarmPrority>
<EndAlarmPrority>0</EndAlarmPrority>
<AlarmMethod>0</AlarmMethod>
<StartTime>2023-10-24T00:00:00</StartTime>
<EndTime>2023-10-24T23:00:00</EndTime>
</Query>
  1. 取消订阅返回
SIP/2.0 200 OK
Call-ID: xxx
Contact: <sip:xxx@192.168.0.111:5060>
Content-Length: 0
CSeq: 26500 SUBSCRIBE
Event: presence;id=xxx
Expires: 0
From: <sip:xxx@192.168.0.107>;tag=xxx
To: <sip:xxx@192.168.0.111>;tag=xxx
User-Agent: SIP UAS V.2016.xxxx
Via: SIP/2.0/UDP 192.168.0.107:5060;rport=5060;branch=xxx

界面展示在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1131280.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

学习笔记-极大似然法与最小二乘法

1、极大似然法&#xff08; maximum likelihood estimation&#xff0c;MLE &#xff09; 极大似然法&#xff08; maximum likelihood estimation&#xff0c;MLE &#xff09;是概率统计中估算模型参数的一种很经典和重要的方法。 &#xff08;1&#xff09;定义 最大似然估…

ArcGIS中批量mxd高版本转低版本

我们经常在给别人发ArcGIS的工程文件mxd&#xff0c;结果到别人那发现mxd工程文件打不开&#xff0c;原因是我们的arcgis版本高于别人&#xff0c;此时工程文件又很多&#xff0c;一个个转存成低版本又嫌麻烦&#xff0c;于是我们做了个批量mxd高版本转低版本的小工具&#xff…

2023平台工程崭露头角,AI 带来新机遇与挑战

在今年&#xff0c;平台工程正在迅速在 IT 企业中崭露头角&#xff0c;成为软件开发团队的必要实践。根据 CloudBees 发布的最新报告《2023年平台工程&#xff1a;快速采纳和影响》&#xff0c;83%的受访者已经完全实施了平台工程&#xff0c;或正处于某种实施阶段。 平台工…

通过VScode连接远程 Linux 服务器修改vue代码

1先在Linux环境安装node&#xff0c;官网下载的node安装包放在自己新建文件夹 2解压 tar -zxvf node-v18.18.0-linux-x64.tar.xz 3新建代码路径&#xff0c; 下载代码 4安装 OpenSSH OpenSSH 可以让你在终端使用 ssh 命令&#xff0c;Windows10 一般自带。 可以通过以下方式…

DC-7 靶机

DC_7 信息搜集 存活检测 详细扫描 后台网页扫描 网页信息搜集 搜索相关信息 在配置中发现了用户名密码字样 $username "dc7user"; $password "MdR3xOgB7#dW";ssh 登录 尝试使用获取的账密进行登录 网页登录失败 尝试 ssh 登录 成功登录 登陆今后提…

迷你洗衣机哪个牌子好又实惠?内裤洗衣机热销前四榜单

小型内裤洗衣机是一款很实用的家用电器&#xff0c;非常适合住在小户型的房子里&#xff0c;或者经常要出差的人。所以&#xff0c;买什么牌子的内衣洗衣机比较好&#xff1f;目前市场上各品牌各有各的特色及应用场合&#xff0c;例如适合于贴身衣物如内衣、内裤、婴儿衣物清洗…

线性表操作的实现--单链表(链式存储结构)

本文参考朱战力老师的数据结构与算法--使用C语言一书 目录 文章目录 前言 一、链表是什么&#xff1f; 二、具体实现 1.单链表的定义 2.初始化ListInitiate&#xff08;SLNode **head&#xff09; 3.求当前元素的个数ListLength&#xff08;SLNode *head&#xff09; 4.插入Lis…

学会Docker之——界面化操作(Docker Desktop)

Docker Desktop 是一款用于在桌面环境下开发、构建和容器化应用程序的工具。它适用于 Windows 和 Mac 操作系统&#xff0c;让开发人员可以轻松地在本地环境中创建和运行容器&#xff0c;并与 Docker Hub 和其他容器注册表进行交互。Docker Desktop集成了Docker Engine&#xf…

C语言文件操作(详解)

&#x1f493;博客主页&#xff1a;江池俊的博客⏩收录专栏&#xff1a;C语言进阶之路&#x1f449;专栏推荐&#xff1a;✅C语言初阶之路 ✅数据结构探索✅C语言刷题专栏&#x1f4bb;代码仓库&#xff1a;江池俊的代码仓库&#x1f389;欢迎大家点赞&#x1f44d;评论&#x…

Maven历史版本下载

网址: https://archive.apache.org/dist/maven/maven-3/3.8.6/binaries/

个人博客测试报告

目录 一、项目背景 二、项目功能 三、测试计划 功能测试 1、测试用例 ​编辑 2、 实际执行测试的部分操作步骤/截图 3、发现的bug 自动化测试 博客访问连接 一、项目背景 个人博客系统采用前后端分离的方法来实现&#xff0c;同时使用了数据库来存储相关的数据&#xf…

文心一言简单体验

百度正式发布文心一言&#xff0c;文心一言 这里的插件模式挺有意思&#xff1a; 测试了一下图解说明&#xff0c;随意上传了一张图片&#xff1a; 提供图解让反过来画&#xff0c;抓住了部分重点&#xff0c;但是还是和原图有比较大的差异&#xff01; 百宝箱 暂未逐个体验&am…

台灯应该买什么样的才能护眼?五款专业的护眼台灯推荐

台灯主要还是以护眼台灯为主&#xff0c;因为不仅色谱丰富&#xff0c;贴近自然色的全光谱色彩&#xff0c;通常显色指数都能达到Ra95以上&#xff0c;显色能力特别强&#xff0c;而且还具有其他防辐射危害、提高光线舒适度的特性&#xff0c;比如侧发光技术、漫反射技术等大大…

Windows更新强制关闭

使用管理员身份运行cmd或者使用powershell 执行下述命令 reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings" /v FlightSettingsMaxPauseDays /t reg_dword /d 36525 /f可以看到更新选项中可以截止到2123年,我感觉比我生命的终点要靠后了! …

设树B是一棵采用链式结构存储的二叉树,编写一个把树 B中所有结点的左、右子树进行交换的函数 中国科学院大学2015年数据结构(c语言代码实现)

本题代码如下 void swap(tree* t) {if (*t)// 如果当前节点非空 {treenode* temp (*t)->lchild;// 临时存储左子节点 (*t)->lchild (*t)->rchild;// 将右子节点赋值给左子节点(*t)->rchild temp;// 将临时存储的左子节点赋值给右子节点 swap(&(*t)->l…

c语言进制的转换10进制转换2进制

c语言进制的转换之10进制转换2进制 c语言10进制转换2进制 c语言进制的转换之10进制转换2进制一、10进制转换2进制的方法 一、10进制转换2进制的方法 十进制转二进制&#xff1a; 除二反序取余法&#xff1a;将十进制数每次除以2 取出余数 按照结果倒叙依次获取结果 END

机器学习实验一:KNN算法,手写数字数据集(使用汉明距离)(2)

KNN-手写数字数据集&#xff1a; 使用sklearn中的KNN算法工具包&#xff08; KNeighborsClassifier)替换实现分类器的构建&#xff0c;注意使用的是汉明距离&#xff1b; 运行结果&#xff1a;&#xff08;大概要运行4分钟左右&#xff09; 代码&#xff1a; import pandas as…

JavaWeb——Servlet原理、生命周期、IDEA中实现一个Servlet(全过程)

6、servlet 6.1、什么是servlet 在JavaWeb中&#xff0c;Servlet是基于Java编写的服务器端组件&#xff0c;用于处理客户端&#xff08;通常是Web浏览器&#xff09;发送的HTTP请求并生成相应的HTTP响应。Servlet运行在Web服务器上&#xff0c;与Web容器&#xff08;如Tomcat&…

警惕!又2本期刊被“On Hold”!

【SciencePub学术】 此前&#xff0c;继一本SSCI期刊被取消“On hold”标识后&#xff0c;仍处于“On Hold”状态的期刊有6本&#xff0c;其中包括4本SCI期刊和2本ESCI期刊。近日&#xff0c;经小编查询&#xff0c;又新增2本“On Hold”期刊&#xff0c;详情如下&#xff1a;…