licode erizo pipleline 1 : handlercontext
licode erizo pipleline
- 今天周末,忙里偷闲,看看大佬 说 绕来绕去的pipeline
- 开始走读代码
看起来部分代码是来自于facebook的网络库
- iqy有大神做了调研 HomeTechnologyFacebook C++网络库Wangle调研
- 里面有个类图,可以参考,迅速搞清楚
HandlerBase
- HandlerBase 模板类,传入一个ctx模板类型,实际传入HandlerContext
- 主要用来绑定或者解除绑定 pipeline
- 友元类 friend PipelineContext;
- 返回 ctx ,与ctx强关联
Handler 是一个接口类
- class Handler 继承自 HandlerBase
class Handler : public HandlerBase<HandlerContext> {
- 定义了很多纯虚方法
- 不是纯虚的都是virtual方法,而且都是通过ctx来做的
virtual void readEOF(Context* ctx) {ctx->fireReadEOF();}virtual void transportActive(Context* ctx) {ctx->fireTransportActive();}virtual void transportInactive(Context* ctx) {ctx->fireTransportInactive();}virtual void write(Context* ctx, std::shared_ptr<DataPacket> packet) = 0;virtual void close(Context* ctx) {return ctx->fireClose();}
inbound/outbound hander 都直接集成handlerbase,而不是handler
- 那handler干啥用?
- 跟handler很像,ctx 也是对应的,而不是handlerctx
class InboundHandler : public HandlerBase<InboundHandlerContext> {public:static const HandlerDir dir = HandlerDir::IN;typedef InboundHandlerContext Context;virtual ~InboundHandler() = default;virtual void enable() = 0;virtual void disable() = 0;virtual std::string getName() = 0;virtual void read(Context* ctx, std::shared_ptr<DataPacket> packet) = 0;virtual void readEOF(Context* ctx) {ctx->fireReadEOF();}virtual void transportActive(Context* ctx) {ctx->fireTransportActive();}virtual void transportInactive(Context* ctx) {ctx->fireTransportInactive();}virtual void notifyUpdate() = 0;virtual void notifyEvent(MediaEventPtr event) {}
};class OutboundHandler : public HandlerBase<OutboundHandlerContext> {public:static const HandlerDir dir = HandlerDir::OUT;typedef OutboundHandlerContext Context;virtual ~OutboundHandler() = default;virtual void enable() = 0;virtual void disable() = 0;virtual std::string getName() = 0;virtual void write(Context* ctx, std::shared_ptr<DataPacket> packet) = 0;virtual void close(Context* ctx) {return ctx->fireClose();}virtual void notifyUpdate() = 0;virtual void notifyEvent(MediaEventPtr event) {}
};
HandlerAdapter 是Handler子类
- Handler的纯虚函数/虚函数,HandlerAdapter都override实现了
class HandlerAdapter : public Handler {public:typedef typename Handler::Context Context;void enable() override {}void disable() override {}std::string getName() override {return "adapter";}void read(Context* ctx, std::shared_ptr<DataPacket> packet) override {ctx->fireRead(std::move(packet));}void write(Context* ctx, std::shared_ptr<DataPacket> packet) override {return ctx->fireWrite(std::move(packet));}void notifyUpdate() override {}void notifyEvent(MediaEventPtr event) override {}
};
HandlerContext
- 这个比in、out的都全
- 能read write transport close
- 管理pipeline,是获取piplebase的入口
class HandlerContext {public:virtual ~HandlerContext() = default;virtual void fireRead(std::shared_ptr<DataPacket> packet) = 0;virtual void fireReadEOF() = 0;virtual void fireTransportActive() = 0;virtual void fireTransportInactive() = 0;virtual void fireWrite(std::shared_ptr<DataPacket> packet) = 0;virtual void fireClose() = 0;virtual PipelineBase* getPipeline() = 0;virtual std::shared_ptr<PipelineBase> getPipelineShared() = 0;
};
In/Out boundHandlerContext
- 不是handlercontext的子类
- 功能与 handlercontext类似,稍有弱化,比如in的不能write,out的不能read
class InboundHandlerContext {public:virtual ~InboundHandlerContext() = default;virtual void fireRead(std::shared_ptr<DataPacket> packet) = 0;virtual void fireReadEOF() = 0;virtual void fireTransportActive() = 0;virtual void fireTransportInactive() = 0;virtual PipelineBase* getPipeline() = 0;virtual std::shared_ptr<PipelineBase> getPipelineShared() = 0;
};class OutboundHandlerContext {public:virtual ~OutboundHandlerContext() = default;virtual void fireWrite(std::shared_ptr<DataPacket> packet) = 0;virtual void fireClose() = 0;virtual PipelineBase* getPipeline() = 0;virtual std::shared_ptr<PipelineBase> getPipelineShared() = 0;
};
=========下面是HandlerContext-in.h
横空出世一个PipeLineContext
- 与handler的ctx是关联关系
class PipelineContext {public:virtual ~PipelineContext() = default;virtual void attachPipeline() = 0;virtual void detachPipeline() = 0;virtual void notifyUpdate() = 0;virtual void notifyEvent(MediaEventPtr event) = 0;virtual std::string getName() = 0;virtual void enable() = 0;virtual void disable() = 0;template <class H, class HandlerContext>void attachContext(H* handler, HandlerContext* ctx) {if (++handler->attachCount_ == 1) {handler->ctx_ = ctx;} else {handler->ctx_ = nullptr;}}virtual void setNextIn(PipelineContext* ctx) = 0;virtual void setNextOut(PipelineContext* ctx) = 0;virtual HandlerDir getDirection() = 0;
};
- 确切的说,pipelinecontent 有方法用来关联handler和handlerctx
template <class H, class HandlerContext>void attachContext(H* handler, HandlerContext* ctx) {if (++handler->attachCount_ == 1) {handler->ctx_ = ctx;} else {handler->ctx_ = nullptr;}}
- 另外,还负责 attach和deattach pipeline
还有俩叫做link的小类
- 看着跟in、out 的handlercontext 功能类似
- 难道这里是针对链路的?
class InboundLink {public:virtual ~InboundLink() = default;virtual void read(std::shared_ptr<DataPacket> packet) = 0;virtual void readEOF() = 0;virtual void transportActive() = 0;virtual void transportInactive() = 0;
};class OutboundLink {public:virtual ~OutboundLink() = default;virtual void write(std::shared_ptr<DataPacket> packet) = 0;virtual void close() = 0;
};`
ContextImplBase
- 依旧是一个模板类
- 实现了PipelineContext(可以理解为一个abstract类?)
template <class H, class Context>
class ContextImplBase : public PipelineContext
- 初始化的时候要传递这俩:PipelineBase 和一个handler
- PipelineBase 好像还没看到呢。。。。
void initialize(std::weak_ptr<PipelineBase> pipeline,std::shared_ptr<H> handler) {pipelineWeak_ = pipeline;pipelineRaw_ = pipeline.lock().get();handler_ = std::move(handler);}
- 管理模板传递的某个类型的handler,一些操作是封装handler实现的
- 对外屏蔽handler的实现
void notifyUpdate() override {handler_->notifyUpdate();}void notifyEvent(MediaEventPtr event) override {handler_->notifyEvent(event);}std::string getName() override {return handler_->getName();}void enable() override {handler_->enable();}void disable() override {handler_->disable();}
- 看起来是把handler和context进行attach、deattach
- handler关联的impl就是 模板传递来的 Context* impl_;
// PipelineContext overridesvoid attachPipeline() override {if (!attached_) {this->attachContext(handler_.get(), impl_);handler_->attachPipeline(impl_);attached_ = true;}}void detachPipeline() override {handler_->detachPipeline(impl_);attached_ = false;}
- 下一个in/out 也是pipeline的context
void setNextIn(PipelineContext* ctx) override {if (!ctx) {nextIn_ = nullptr;return;}auto nextIn = dynamic_cast<InboundLink*>(ctx);if (nextIn) {nextIn_ = nextIn;}}void setNextOut(PipelineContext* ctx) override {if (!ctx) {nextOut_ = nullptr;return;}auto nextOut = dynamic_cast<OutboundLink*>(ctx);if (nextOut) {nextOut_ = nextOut;}}
ContextImpl
有点失控了,这个类继承了那么多不同的基类
- 这三个当做是抽象类看待
public HandlerContext,public InboundLink,public OutboundLink,
- 继承这个类决定了context一定是HandlerContext, Handler不确定
ContextImplBase<H, HandlerContext>
初始化用上了
this->impl_ = this;
- ContextImpl 继承自 HandlerContext
- ContextImpl 继承自 ContextImplBase<H, HandlerContext>
- 所以 ContextImpl自己也是 HandlerContext
explicit ContextImpl(std::weak_ptr<PipelineBase> pipeline,std::shared_ptr<H> handler) {this->impl_ = this;this->initialize(pipeline, std::move(handler));}
ContextImpl 类
template <class H>
class ContextImpl: public HandlerContext,public InboundLink,public OutboundLink,public ContextImplBase<H, HandlerContext> {public:static const HandlerDir dir = HandlerDir::BOTH;explicit ContextImpl(std::weak_ptr<PipelineBase> pipeline,std::shared_ptr<H> handler) {this->impl_ = this;this->initialize(pipeline, std::move(handler));}// For StaticPipelineContextImpl() {this->impl_ = this;}~ContextImpl() = default;// HandlerContext overridesvoid fireRead(std::shared_ptr<DataPacket> packet) override {auto guard = this->pipelineWeak_.lock();if (this->nextIn_) {this->nextIn_->read(std::move(packet));}}void fireReadEOF() override {auto guard = this->pipelineWeak_.lock();if (this->nextIn_) {this->nextIn_->readEOF();}}void fireTransportActive() override {auto guard = this->pipelineWeak_.lock();if (this->nextIn_) {this->nextIn_->transportActive();}}void fireTransportInactive() override {auto guard = this->pipelineWeak_.lock();if (this->nextIn_) {this->nextIn_->transportInactive();}}void fireWrite(std::shared_ptr<DataPacket> packet) override {auto guard = this->pipelineWeak_.lock();if (this->nextOut_) {this->nextOut_->write(std::move(packet));}}void fireClose() override {auto guard = this->pipelineWeak_.lock();if (this->nextOut_) {this->nextOut_->close();}}PipelineBase* getPipeline() override {return this->pipelineRaw_;}std::shared_ptr<PipelineBase> getPipelineShared() override {return this->pipelineWeak_.lock();}// InboundLink overridesvoid read(std::shared_ptr<DataPacket> packet) override {auto guard = this->pipelineWeak_.lock();this->handler_->read(this, std::move(packet));}void readEOF() override {auto guard = this->pipelineWeak_.lock();this->handler_->readEOF(this);}void transportActive() override {auto guard = this->pipelineWeak_.lock();this->handler_->transportActive(this);}void transportInactive() override {auto guard = this->pipelineWeak_.lock();this->handler_->transportInactive(this);}// OutboundLink overridesvoid write(std::shared_ptr<DataPacket> packet) override {auto guard = this->pipelineWeak_.lock();this->handler_->write(this, std::move(packet));}void close() override {auto guard = this->pipelineWeak_.lock();this->handler_->close(this);}
};
OutboundContextImpl
template <class H>
class OutboundContextImpl: public OutboundHandlerContext,public OutboundLink,public ContextImplBase<H, OutboundHandlerContext> {public:static const HandlerDir dir = HandlerDir::OUT;explicit OutboundContextImpl(std::weak_ptr<PipelineBase> pipeline,std::shared_ptr<H> handler) {this->impl_ = this;this->initialize(pipeline, std::move(handler));}// For StaticPipelineOutboundContextImpl() {this->impl_ = this;}~OutboundContextImpl() = default;// OutboundHandlerContext overridesvoid fireWrite(std::shared_ptr<DataPacket> packet) override {auto guard = this->pipelineWeak_.lock();if (this->nextOut_) {return this->nextOut_->write(std::move(packet));}}void fireClose() override {auto guard = this->pipelineWeak_.lock();if (this->nextOut_) {return this->nextOut_->close();}}PipelineBase* getPipeline() override {return this->pipelineRaw_;}std::shared_ptr<PipelineBase> getPipelineShared() override {return this->pipelineWeak_.lock();}// OutboundLink overridesvoid write(std::shared_ptr<DataPacket> packet) override {auto guard = this->pipelineWeak_.lock();return this->handler_->write(this, std::move(packet));}void close() override {auto guard = this->pipelineWeak_.lock();return this->handler_->close(this);}
};
ContentImplBase 看了这么久,最关键的还是这个base啊
template <class H, class Context>
class ContextImplBase : public PipelineContext {public:~ContextImplBase() = default;H* getHandler() {return handler_.get();}void initialize(std::weak_ptr<PipelineBase> pipeline,std::shared_ptr<H> handler) {pipelineWeak_ = pipeline;pipelineRaw_ = pipeline.lock().get();handler_ = std::move(handler);}void notifyUpdate() override {handler_->notifyUpdate();}void notifyEvent(MediaEventPtr event) override {handler_->notifyEvent(event);}std::string getName() override {return handler_->getName();}void enable() override {handler_->enable();}void disable() override {handler_->disable();}// PipelineContext overridesvoid attachPipeline() override {if (!attached_) {this->attachContext(handler_.get(), impl_);handler_->attachPipeline(impl_);attached_ = true;}}void detachPipeline() override {handler_->detachPipeline(impl_);attached_ = false;}void setNextIn(PipelineContext* ctx) override {if (!ctx) {nextIn_ = nullptr;return;}auto nextIn = dynamic_cast<InboundLink*>(ctx);if (nextIn) {nextIn_ = nextIn;}}void setNextOut(PipelineContext* ctx) override {if (!ctx) {nextOut_ = nullptr;return;}auto nextOut = dynamic_cast<OutboundLink*>(ctx);if (nextOut) {nextOut_ = nextOut;}}HandlerDir getDirection() override {return H::dir;}protected:Context* impl_;std::weak_ptr<PipelineBase> pipelineWeak_;PipelineBase* pipelineRaw_;std::shared_ptr<H> handler_;InboundLink* nextIn_{nullptr};OutboundLink* nextOut_{nullptr};private:bool attached_{false};
};
licode erizo pipleline 1 : handlercontext相关推荐
- Licode(一):入门介绍
什么是webrtc? WebRTC(Web Real-Time Communication)是一个开源项目(2010年5月,Google以6820万美元收购VoIP软件开发商Global IP Sol ...
- licode 学习总结
licode 学习总结 参考: licode编译以及源码分析:https://www.cnblogs.com/limedia/category/1350712.html Licode-基于webrtc ...
- Licode—基于webrtc的SFU/MCU实现
1. webrtc浅析 webrtc的前世今生.编译方法.行业应用.最佳实践等技术与产业类的文章在网上卷帙浩繁,重复的内容我不再赘述.对我来讲,webrtc的概念可以有三个角度去解释: (1).一个W ...
- Licode 环境搭建
Licode 环境搭建 系统配置 阿里云服务器 Ubuntu 14.04.5 LTS Docker 环境搭建 在一台空的机器上搭建docker环境,先要安装docker,执行下面的命令即可: apt- ...
- 阿里云上搭建webRTC 服务器——Licode
阿里云上搭建webRTC 服务器--Licode 系统配置 阿里云服务器 Ubuntu 14.04.5 LTS Docker 环境搭建 在一台空的机器上搭建docker环境,先要安装docker,执行 ...
- Wangle源码分析:Pipeline、Handler、Context
2019独角兽企业重金招聘Python工程师标准>>> 基本概念 Wangle中的Pipeline和Netty中的Pipeline是很相似的,既可以将它看为一种职责链模式的实现也可以 ...
- 流媒体服务器——Licode Janus-gateway Mediasoup Medooze 分析
目录 前言 Licode Janus-gateway Mediasoup Medooze 前言 已知的多方通信框架有:Mesh MCU SFU 三种.<三种方案的详细介绍> 其中SFU是目 ...
- Licode Docker映像
Licode Docker映像 要运行Licode docker容器,您有两个选择: 您可以使用我们提供的Dockerfile构建自己的映像,然后从中运行容器或 您可以直接从Docker Hub中提供 ...
- Kotlin协程:挂起与恢复原理逆向刨析
前言:只有在那崎岖的小路上不畏艰险奋勇攀登的人,才有希望达到光辉的顶点. --马克思 前言 经过前面两篇协程的学习,我相信大家对协程的使用已经非常熟悉了.本着知其然更要知其之所以然的心态,很想知道它里 ...
最新文章
- 中国云计算厂商营收排名:阿里云完虐微软
- linq学习笔记(2):DataContext
- python英语单词库-python-data-英语单词
- 工具介绍:SUN CAM阵列管理客户端
- 记账本------4
- C语言中三块“难啃的硬骨头”
- 17-Flutter移动电商实战-首页_楼层区域的编写
- qtscrcpy自定义按键_按键映射说明.md
- 信息学奥赛一本通C++语言——1107:校门外的树
- linux-文件与目录权限-0913
- Linux 文件系统 软/硬链接文件
- 菜鸟的学习之路(6) — 设计模式之单例模式(Singleton)
- Eclipse 汉化包下载安装
- Vue指令之v-show
- MySql重启命令与数据库安装目录
- 修改Tomcat8 内存
- matlab软件进行仿真验证,matlab仿真软件
- 优点家庭服务器如何修改wifi密码,家用wifi怎么改密码?
- python后缀是什么_python文件的后缀名是什么
- 【JavaEE】Day11-多线程