目录
音视频融合通信系统架构 1
主要功能包括: 1
系统架构图 1
概要设计 2
一 引言 2
二 基本约定 3
三 系统设计 5
4 验证和授权 10
四 CMS 设计 11
五 CMQ 设计 11
六 SMS 设计 12
七 报警消息设计 14
八 Device Host 设计 14
九 Device Component 设计 14
GB/T 28181 标准平台对接 18
十一 流媒体应用平台 SDK 设计 18
三 系统设计
1 系统结构图
一套完整的流媒体应用系统由平台基础(核心)部分和 DVS 设备接入部分组成。其中:
· 平台基础(核心)部分的 3 种服务是不可选配的,它由一个 CMS 服务、一个 CMQ 服务和一个或多个 SMS 服务组成,这 3 种服务缺一不可;
· 每个平台可以接入一个或多个 DeviceHost 服务,该服务通过平台配置的 DVS 组件信息来控制其运行并监视其运行状态;
· 每个 DeviceHost 服务在同一时刻可以控制和监视一个或多个不同类型的 DVS 组件(如 DC_HIK, DC_GB28181 等),但同一类型的 DVS 组件在同一时刻只能隶属于一个 DeviceHost 服务。
做为流媒体应用平台的服务,它必须尽可能适应各种各样不同格式的流媒体数据。所以流媒体应用平台提供了可扩展的应用部分,这些可扩展的服务作为流媒体应用平台内部和外部数据的桥梁,以流媒体应用平台内部数据为基础,向平台外部提供更多、更丰富的数据展示。另外,可扩展部分的服务可以是由我们自己按照一定的需求来完成,也可以由第三方通过遵照我们平台 API 接口的方式来完成。最后,将可扩展的服务部署到平台上即可使用。
鉴于流媒体应用平台系统在不同行业中的应用场景需求,平台与平台间必须包含上下级级联结构,其基本规则如下:
· 平台内的资源只能由该平台管理员进行配置和修改,其他任何上级和下级平台都无权进行操作;
· 下级平台主动向它隶属的上一级平台推送该平台内的所有资源信息以及相应的变更通知或报警通知等;
· 上级平台能够请求播放隶属于它自己的所有下级平台内的流媒体数据,但下级平台不能请求播放上级平台的流媒体数据;
· 隶属于同一个上级的兄弟平台间不能请求播放流媒体数据。
#include "boost/checked_delete.hpp"
#include "boost/bind/bind.hpp"
using namespace boost::placeholders;
#include "libxmq/switcher.h"
#include "libxmq/publisher.h"
using namespace module::network::xmq;
#include "error_code.h"
#include "utils/thread/thread.h"
#include "utils/thread/thread_pool.h"
using namespace framework::utils::thread;
#include "network/mq/switcher_pub.h"
using namespace framework::network::mq;
SwitcherPub::SwitcherPub()
: switcher{nullptr}, publisher{nullptr}, thread{nullptr}, stopped{ false }
{}
SwitcherPub::~SwitcherPub()
{
stop();
}
int SwitcherPub::start(
const unsigned short switcherPort /* = 0 */,
const unsigned short publisherPort /* = 0 */,
const int hwm /* = 10 */)
{
int ret{ !switcher && !publisher ? Error_Code_Success : Error_Code_Object_Existed};
if (Error_Code_Success == ret)
{
ret = (0 < switcherPort && 0 < publisherPort ? Error_Code_Success : Error_Code_Invalid_Param);
if(Error_Code_Success == ret)
{
Switcher* ps{
new(std::nothrow) Switcher(
boost::bind(&SwitcherPub::afterSwitcherPolledDataHandler, this, _1, _2))};
Publisher* pp{new(std::nothrow) Publisher()};
if(ps && Error_Code_Success == ps->bind(switcherPort) &&
pp && Error_Code_Success == pp->bind(publisherPort, hwm))
{
thread = ThreadPool().get_mutable_instance().createNew(
boost::bind(&SwitcherPub::pollDataFromSwitcherThread, this));
switcher = ps;
publisher = pp;
}
else
{
boost::checked_delete(ps);
boost::checked_delete(pp);
ret = Error_Code_Bad_New_Object;
}
}
}
return ret;
}
int SwitcherPub::stop()
{
stopped = true;
Thread().join(thread);
ThreadPool().get_mutable_instance().destroy(thread);
boost::checked_delete(switcher);
boost::checked_delete(publisher);
switcher = nullptr;
publisher = nullptr;
return Error_Code_Success;
}
int SwitcherPub::send(
const std::string uid,
const std::string data)
{
int ret{ switcher ? Error_Code_Success : Error_Code_Object_Existed };
if (Error_Code_Success == ret)
{
Switcher* ps{reinterpret_cast<Switcher*>(switcher)};
ret = ps->send(uid, data);
}
return ret;
}
int SwitcherPub::send(
const std::string data)
{
int ret{ publisher ? Error_Code_Success : Error_Code_Object_Existed };
if (Error_Code_Success == ret)
{
Publisher* pp{reinterpret_cast<Publisher*>(publisher)};
ret = pp->send(data);
}
return ret;
}
void SwitcherPub::pollDataFromSwitcherThread()
{
while (!stopped)
{
Switcher* switcher{reinterpret_cast<Switcher*>(this->switcher)};
switcher->poll();
}
}