Reactor模式是一种事件驱动的编程模式,用于高效处理并发I/O操作,通过一个或多个事件循环来监听和处理各种事件,从而实现高效的并发处理,而无需为每一个连接创建一个线程或进程。

reactor里管理每一个添加进来的connetion,当有事件就绪了就返回到就绪事件数组中每一个connection类都有一个回指reactor的指针便于后续调用reactor类内方法;
connection基类:
`#pragma once
//fd对应一个connection连接
include
include
include
include"InetAddr.hpp"
include<errno.h>
include <sys/epoll.h>
include"Common.hpp"
class Reactor;
class Connection
{
public:
Connection()
:_events(0)
{}
uint32_t Events(){return _events;}
void SetEvents(uint32_t events){_events=events;}
void SetAddress(const InetAddr &addr)
{
_clientaddr=addr;
}
virtual int Sockfd()=0;
virtual void Recver()=0;
virtual void Sender()=0;
virtual void Close()=0;
virtual void Excepter()=0;
~Connection(){}
protected:
InetAddr _clientaddr;
uint32_t _events;
public:
Reactor * _R;
};`
listener子类:
class Listener : public Connection
{
public:
Listener(uint16_t port, OnMessage_t onmessage) : _port(port), _on_message(onmessage), _listensock(std::make_unique
{
_listensock->BuildSocketMethod(_port);
SetNonBlock(_listensock->Socketfd());
}
int Sockfd() override
{
return _listensock->Socketfd();
}
void Recver() override
{
LOG(LogLevel::INFO) << "listen event ready fd:" << _listensock->Socketfd();
while (true)
{
int errocode = 0;
InetAddr claddr;
int socket = _listensock->Accepter(&claddr,&errocode);
if (socket >= 0)
{
// 又有一个读事件了我得创一个io连接
std::shared_ptr
SetNonBlock(socket);
int flags = fcntl(socket, F_GETFL, 0);
LOG(LogLevel::ERROR) << "O_NONBLOCK=" << ((flags & O_NONBLOCK) ? "yes" : "no");
conn->SetEvents(EPOLLIN | EPOLLET);
//conn->SetEvents(EPOLLIN );
conn->SetAddress(claddr);
_R->Addconnection(conn);//添加到reactor中
LOG(LogLevel::INFO) << "accepte success";
}
else
{
if(errocode== EAGAIN||errocode EWOULDBLOCK)
{
LOG(LogLevel::INFO)<<"accepter finish!";
break;
}
if(errocodeEINTR)
{
LOG(LogLevel::INFO)<<"accepter interupt!";
continue;
}
else{
LOG(LogLevel::ERROR)<<"accepter error";
break;
}
}
}
}
void Close() override
{
_listensock->Close();
}
void Sender() override
{
// listen忽略
}
void Excepter() override
{
// 忽略
}
~Listener()
{
}
private:
uint16_t _port;
OnMessage_t _on_message;
std::unique_ptr
};
IOhander子类:
include "Connection.hpp"
include
include
include"Log.hpp"
include"Calculator.hpp"
using namespace LogModule;
using OnMessage_t = std::function<std::string(std::string &, int *code)>;
static const int gbuffersize = 1024;
class IOHandler : public Connection
{
public:
IOHandler(int sockfd, OnMessage_t message) : _sockfd(sockfd), _on_message(message) {}
int Sockfd() override
{
return _sockfd;
}
void Recver() override
{
LOG(LogLevel::INFO)<<"iorecver";
char buffer[gbuffersize];
while (true)
{
ssize_t n = recv(_sockfd, buffer, sizeof(buffer) - 1, 0);
if (n > 0)
{
buffer[n]=0;
_inbuffer+=buffer;
}
else if(n0)
{
LOG(LogLevel::DEBUG)<<"client quit ,address is "<<_clientaddr.StringAddress()<<"sockfd"<<_sockfd;
Excepter();
return ;
}
else
{
if(errnoEAGAIN||errnoEWOULDBLOCK)
{
break;
}
else if(errnoEINTR)
{
continue;
}
else{
LOG(LogLevel::ERROR)<<"recv error ,address is "<<_clientaddr.StringAddress()<<"sockfd"<<_sockfd;
Excepter();
return;
}
}
}
int code =0;
std::string result=_on_message(_inbuffer,&code);
std::cout<<result.c_str()<<"code: "<<code<<std::endl;
_inbuffer.clear();
if(code==0)
{
_outbuffer+=result;
std::cout<<_outbuffer.c_str()<<std::endl;
}
else{
Excepter();
return ;
}
if(!_outbuffer.empty())
_R->EnableReadWrite(_sockfd,true,true);
}
void Sender() override
{
while(true)
{
ssize_t n=send(_sockfd,_outbuffer.c_str(),_outbuffer.size(),0);
LOG(LogLevel::INFO) << "send n=" << n << " errno=" << errno << " remain=" << _outbuffer.size();
if(n>=0)
{
_outbuffer.erase(0,n);
if(_outbuffer.empty())
{
LOG(LogLevel::INFO) << "send n=0, close";
break;
}
}
else
{
if(errno EAGAIN||errnoEWOULDBLOCK)
{
break;
}
else if(errno==EINTR)
{
continue;
}
else{
LOG(LogLevel::ERROR)<<"send error"<<_clientaddr.StringAddress()<<"_sockfd"<<_sockfd;
Excepter();
return;
}
}
}
LOG(LogLevel::DEBUG) << "Sender exit fd=" << _sockfd << " outbuf=" << _outbuffer.size();
if(_outbuffer.empty())
_R->EnableReadWrite(_sockfd,true,false);
else
_R->EnableReadWrite(_sockfd,true,true);
}
void Close() override
{
// close(_sockfd);
}
void Excepter()override
{
_R->Delconnection(_sockfd);
}
~IOHandler() {}
private:
int _sockfd;
OnMessage_t _on_message;
std::string _inbuffer;
std::string _outbuffer;
};
////////////////以上为链接类reactor管理这些类////////////////////
`#include "Connection.hpp"
include <unordered_map>
include "Poller.hpp"
const int sum = 1024;
class Reactor
{
private:
bool IsConnectionExits(int sockfd)
{
return _connections.find(sockfd) != _connections.end();
}
public:
Reactor()
: _epoller(std::make_unique
void Addconnection(std::shared_ptr
{
int sockfd = conn->Sockfd();
uint32_t events = conn->Events();
_epoller->Addevents(sockfd, events);
_connections[sockfd] = conn;
conn->_R = this;
LOG(LogLevel::INFO) << "addconnect scucess"<<"fd: "<<sockfd;
std::cout<<_connections[sockfd]->Sockfd()<<std::endl;
}
void EnableReadWrite(int sockfd,bool enableread,bool enablewrite)
{
if(!IsConnectionExits(sockfd))
{
return;
}
uint32_t events =((enableread? EPOLLIN :0) |(enablewrite ? EPOLLOUT:0)|EPOLLET);
_connections[sockfd]->SetEvents(events);
_epoller->Modevents(sockfd,events);
}
void Delconnection(int sockfd)
{
_epoller->Dellevents(sockfd);
_connections[sockfd]->Close();
_connections.erase(sockfd);
}
void LoopOnce(int timeout)//用来等待并处里事件
{
std::cout<<"LOOPONCE"<<std::endl;
int n = _epoller->WaitEvent(revs, sum, timeout);
std::cout<<"个数"<<n<<std::endl;
if (n > 0)
{
for (int i = 0; i < n; i++)
{
int fd = revs[i].data.fd;
uint32_t events = revs[i].events;
LOG(LogLevel::DEBUG) << "event fd=" << fd << " events=" << events;
if ((events & EPOLLERR) || (events & EPOLLHUP))
events = (EPOLLIN | EPOLLOUT);
if (events & EPOLLIN)
_connections[fd]->Recver();
if (events & EPOLLOUT)
_connections[fd]->Sender();
}
}
}
void ConnnectionKeepAlive()
{
//
}
void Dispatcher()
{
int timeout = -1;
while (true)
{
LoopOnce(timeout);
ConnnectionKeepAlive();
}
}
~Reactor() {};
private:
std::unique_ptr
std::unordered_map<int, std::shared_ptr
struct epoll_event revs[sum];
};`
当我们创建一个listener添加到创建的reactor类中,reactor会将listenner的fd添加进epoll中再循环等待就绪listener会accept
在listener内部accept的到的fd会创建以iohander类并用回指指针调用添加函数加入到reactor中就绪后就可以调用各类内的io进行读写操作
读写操作上层就交个业务模块处理了
浙公网安备 33010602011771号