ChatServer
redis 的多个功能
redis运行不稳定怎么办,挂了怎么办
send返回成功,只能说明拷贝到缓冲区了
mymuduo
Linux下的IO模型
Reactor模型
重要组件:Event事件、Reactor反应堆、Demultiplex事件分发器、Evanthandler事件处理器
muduo库的Multiple Reactors模型如下:
并不是生产消费模型,而是,用wakeupfd唤醒,效率非常高
muduo库函数调用 回调函数:
TchoServer:
server_.setConnectionCallback(std::bind(&EchoServer::onConnection, this, std::placeholders::_1));
server_.setMessageCallback(std::bind(&EchoServer::onMessage, this,std::_1, std::_2, std::_3));
void onConnection(const TcpConnectionPtr &conn)
{
if (conn->connected())
{
LOG_INFO("Connection UP : %s", conn->peerAddress().toIpPort().c_str());
}
else
{
LOG_INFO("Connection DOWN : %s", conn->peerAddress().toIpPort().c_str());
}
}
// 可读写事件回调
void onMessage(const TcpConnectionPtr &conn,
Buffer *buf,
Timestamp time)
{
std::string msg = buf->retrieveAllAsString();
conn->send(msg);
conn->shutdown(); // 写端 EPOLLHUP =》 closeCallback_
}
};
TcpServer:
void setConnectionCallback(const ConnectionCallback &cb) { connectionCallback_ = cb; }
void setMessageCallback(const MessageCallback &cb) { messageCallback_ = cb; }
acceptor_->setNewConnectionCallback(std::bind(&TcpServer::newConnection, this, _1, _2));
void TcpServer::newConnection(int sockfd, const InetAddress &peerAddr){
TcpConnectionPtr conn(new TcpConnection( ...));
conn->setConnectionCallback(connectionCallback_);
conn->setMessageCallback(messageCallback_);//并没有bind一个具体的函数而是,而是直接TcpServer中的connectionCallback_
}
TcpServer和TcpConnection都有messageCallback_ connectionCallback_
有两个handleRead 一个是&Acceptor::handleRead &TcpConnection::handleRead 一个处理新连接的建立 一个处理已经连接事件的读写;
Acceptor:
void setNewConnectionCallback(const NewConnectionCallback &cb) {newConnectionCallback_ = cb;}
acceptChannel_.setReadCallback(std::bind(&Acceptor::handleRead, this));
TcpConnection:
void TcpConnection::connectEstablished(){connectionCallback_(shared_from_this());}
void setConnectionCallback(const ConnectionCallback& cb) { connectionCallback_ = cb; }
void setMessageCallback(const MessageCallback& cb) { messageCallback_ = cb; }
channel_->setReadCallback(std::bind(&TcpConnection::handleRead, this, std::placeholders::_1));
void TcpConnection::handleRead(Timestamp receiveTime){ messageCallback_(shared_from_this(), &inputBuffer_, receiveTime);}
channel:
epoll检测出读事件,给channel通知,channel调用读事件,由上层具体设置回调函数
void setReadCallback(ReadEventCallback cb) { readCallback_ = std::move(cb); }
void Channel::handleEventWithGuard(Timestamp receiveTime){
if(revents_ & EPOLLHUP) && !(revents_ & EPOLLIN) readCallback_(receiveTime);
}