前提:这个WebServer版本不是牛客网上的那一个,这个版本是GitHub - linyacool/WebServer: A C++ High Performance Web Server,用的是Reactor模型
同时,这是自己学习的时候的个人理解,以及个人分析,所以可能分析有误,欢迎指正交流。
Channel类的主要作用:用于回调
与Channel类相关的类:
(1)EventLoop类:通过EventLoop中的loop()函数得到一系列事件Channel,封装到一个vector里面去,然后for循环调用Channel.h类中的函数handleEvents(),Channel函数去进行回调,然后跳到HttpDate类进行实际的处理(实际处理是在HttpDate类中)
void EventLoop::loop() {
assert(!looping_);
assert(isInLoopThread());
looping_ = true;
quit_ = false;
// LOG_TRACE << "EventLoop " << this << " start looping";
//一个vector,每一个元素都是Channel类(事件回调)
std::vector<SP_Channel> ret;
while (!quit_) {
// cout << "doing" << endl;
ret.clear();
ret = poller_->poll();
eventHandling_ = true;
//循环取出Channel,去通过handleEvents函数去处理,Channel进行回调,实际处理函数是在HttpData类中
for (auto& it : ret) it->handleEvents();
eventHandling_ = false;
doPendingFunctors();
poller_->handleExpired();
}
looping_ = false;
}
(2)HttpData类:一个Channel与一个HttpDate类绑定,如果Channel是读事件,那么通过Channel回调去调用HttpData类里面的读处理
具体的部分逻辑代码实现如下,以写事件为例(读实件以及连接事件同理)
/*Channel中设置回调函数,Channel.h中*/
void setReadHandler(CallBack &&readHandler) { readHandler_ = readHandler; }
void setWriteHandler(CallBack &&writeHandler) {
writeHandler_ = writeHandler;
}
/*HttpData的构造函数中将Channel的回调绑定HttpData中具体的处理函数*/
HttpData::HttpData(EventLoop *loop, int connfd)
: loop_(loop),
channel_(new Channel(loop, connfd)),
fd_(connfd),
error_(false),
connectionState_(H_CONNECTED),
method_(METHOD_GET),
HTTPVersion_(HTTP_11),
nowReadPos_(0),
state_(STATE_PARSE_URI),
hState_(H_START),
keepAlive_(false) {
// loop_->queueInLoop(bind(&HttpData::setHandlers, this));
//绑定
channel_->setReadHandler(bind(&HttpData::handleRead, this));
channel_->setWriteHandler(bind(&HttpData::handleWrite, this));
channel_->setConnHandler(bind(&HttpData::handleConn, this));
}
/*当Channel中的事件为写事件的时候,通过绑定,可以实现具体的写实件,具体的写事件在HttpData函数中实现*/
void HttpData::handleWrite() {
if (!error_ && connectionState_ != H_DISCONNECTED) {
__uint32_t &events_ = channel_->getEvents();
if (writen(fd_, outBuffer_) < 0) {
perror("writen");
events_ = 0;
error_ = true;
}
if (outBuffer_.size() > 0) events_ |= EPOLLOUT;
}
}
未完待续...有点子看不懂了