高性能RTSP服务器,代码分析2,EventScheduler包含的三种Event处理方法

在这里插入图片描述

EventScheduler包含三种Event的处理方法。

1.TriggerEvent ,从它的的callback函数可以看出,主要处理RtspServer::cbCloseConnect关闭连接
2.TimerEvent,服务于流媒体的sink实例发送视频
3.IOEvent. 通过select poller处理socketfd连接事件
在这里插入图片描述

Windows不能使用select poller来调度定时器事件,而linux却可以。
在这里插入图片描述

下面函数将TimerEvent加入了调度器:
void Sink::runEvery(int interval){
mTimerId = mEnv->scheduler()->addTimedEventRunEvery(mTimerEvent, interval);
}

TimerMananger的核心函数是handleRead:
这个核心函数会调用timer.handleEvent函数:bool timerEventIsStop = timer.handleEvent();
void TimerManager::readCallback(void arg) {
TimerManager
timerManager = (TimerManager*)arg;
timerManager->handleRead();
}
void TimerManager::handleRead() {

//LOGI("mTimers.size()=%d,mEvents.size()=%d",mTimers.size(),mEvents.size());
Timer::Timestamp timestamp = Timer::getCurTime();
if (!mTimers.empty() && !mEvents.empty()) {

    std::multimap<Timer::Timestamp, Timer>::iterator it = mEvents.begin();
    Timer timer = it->second;
    int expire = timer.mTimestamp - timestamp;

    //LOGI("timestamp=%d,mTimestamp=%d,expire=%d,timeInterval=%d", timestamp, timer.mTimestamp, expire, timer.mTimeInterval);

    if (timestamp > timer.mTimestamp || expire == 0) {

        bool timerEventIsStop = timer.handleEvent();
        mEvents.erase(it);
        if (timer.mRepeat) {
            if (timerEventIsStop) {
                mTimers.erase(timer.mTimerId);
            }else {
                timer.mTimestamp = timestamp + timer.mTimeInterval;
                mEvents.insert(std::make_pair(timer.mTimestamp, timer));
            }
        }
        else {
            mTimers.erase(timer.mTimerId);
        }

    }
}
modifyTimeout();

}

bool Timer::handleEvent()
{
if (!mTimerEvent) {
return false;
}
return mTimerEvent->handleEvent();

}

bool TimerEvent::handleEvent()
{
if (mIsStop) {
return mIsStop;
}

if(mTimeoutCallback)
    mTimeoutCallback(mArg);

return mIsStop;

}

Sink的构造函数会调用setTimeoutCallback函数,设置timeout的回调函数cbTimeout。
void setTimeoutCallback(EventCallback cb) { mTimeoutCallback = cb; }
Sink::Sink(UsageEnvironment* env, MediaSource* mediaSource, int payloadType) :
mMediaSource(mediaSource),
mEnv(env),
mCsrcLen(0),
mExtension(0),
mPadding(0),
mVersion(RTP_VESION),
mPayloadType(payloadType),
mMarker(0),
mSeq(0),
mSSRC(rand()),
mTimestamp(0),
mTimerId(0),
mSessionSendPacket(NULL),
mArg1(NULL),
mArg2(NULL)
{

LOGI("Sink()");
mTimerEvent = TimerEvent::createNew(this);
mTimerEvent->setTimeoutCallback(cbTimeout);

}

void Sink::cbTimeout(void arg) {
Sink
sink = (Sink*)arg;
sink->handleTimeout();
}
void Sink::handleTimeout() {
MediaFrame* frame = mMediaSource->getFrameFromOutputQueue();
if (!frame) {
return;
}
this->sendFrame(frame);// 由具体子类实现发送逻辑

mMediaSource->putFrameToInputQueue(frame);//将使用过的frame插入输入队列,插入输入队列以后,加入一个子线程task,从文件中读取数据再次将输入写入到frame

}

Sink的下面函数会把mTimerEvent注册到scheduler调度器:
void Sink::runEvery(int interval){
mTimerId = mEnv->scheduler()->addTimedEventRunEvery(mTimerEvent, interval);
}

:

从下图的引用看出,只有RtspServer和TcpConnection调用了IOEvent的构造函数,来构造IOEvent.

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

:
RtspServer的handleRead函数收到有客户端连接进来后,会建立RtspConnection的实例。RtspConnection类是继承于TcpConnction类。
然后mConnMap.insert(std::make_pair(clientFd, conn));会将改客户端的id和连接信息,插入到mConnMap中。
在这里插入图片描述

RtspConnection调用TcpConnection构造函数
在这里插入图片描述
TcpConnection构造函数产生一个IOEvent,并把这个IOEvent加入到调度器scheduler中。
在这里插入图片描述

RtspServer start函数和TcpConnection的构造函数中会增加IOEvent.
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
RtspServer和TcpConnection的析构函数中会removeIOEvent.
在这里插入图片描述
在这里插入图片描述

selectpoller继承与顶级父类poller:
class SelectPoller : public Poller
virtual bool addIOEvent(IOEvent* event) = 0;
virtual bool updateIOEvent(IOEvent* event) = 0;
virtual bool removeIOEvent(IOEvent* event) = 0;
virtual void handleEvent() = 0;
selectpoller类实现了顶级父类的纯虚函数:
virtual bool addIOEvent(IOEvent* event);
virtual bool updateIOEvent(IOEvent* event);
virtual bool removeIOEvent(IOEvent* event);
virtual void handleEvent();

RtspServer::RtspServer
中创建了TcpSock IO Event
mFd = sockets::createTcpSock();
mAcceptIOEvent = IOEvent::createNew(mFd, this);

TcpConnection::TcpConnection
中创建了clientFd IO Event
mClientIOEvent = IOEvent::createNew(clientFd, this);

void RtspServer::handleRead()
->tspConnection* conn = RtspConnection::createNew(this, clientFd);
->RtspConnection::RtspConnection(RtspServer* rtspServer, int clientFd)
->class RtspConnection : public TcpConnection
RtspConnection继承于TcpConnection。
TcpConnection(UsageEnvironment* env, int clientFd);
TcpConnection的构造函数中中创建了clientFd IO Event

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值