void doUnsubscribe(const TcpConnectionPtr& conn, const string& topic) { LOG_OK << conn->name() << " unsub " << topic; getTopic(topic).remove(conn); // topic could be the one to be destroyed, so don't use it after erasing. //客户端不订阅某个topic,就销毁 ConnectionSubscription* connSub = boost::any_cast<ConnectionSubscription>(conn->getMutableContext()); connSub->erase(topic); }
//TODO:这个函数没有处理客户端sub的topic不存在的情况 void doSubscribe(const TcpConnectionPtr& conn, const string& topic) { //getMutableContext返回的是:boost::any* //为什么any_cast用的是ConnectionSubscripton,而不是指针???看boost:any_cast原型 /* template<typename ValueType> ValueType * any_cast(any * operand) */ LOG_OK << conn->name() << " sub " << topic; ConnectionSubscription* connSub = boost::any_cast<ConnectionSubscription>(conn->getMutableContext()); connSub->insert(topic);//保存这个客户端订阅的主题 getTopic(topic).add(conn); }
void HttpServer::onMessage(const TcpConnectionPtr& conn, ByteBuffer *buf, Timestamp receiveTime) { LOG_INFO("HttpServer::onConnection recv data [%d][%s]", conn->fd(), buf->toString().c_str()); HttpContext *context = zl::stl::any_cast<HttpContext>(conn->getMutableContext()); assert(context); if(!context->parseRequest(buf, receiveTime)) { conn->send("HTTP/1.1 400 Bad Request\r\n\r\n"); conn->send("HTTP/1.1 400 Bad Request\r\n\r\n"); conn->shutdown(); } if (context->gotAll()) { LOG_INFO("HttpServer::onMessage parse request over."); response(conn, context->request()); context->reset(); // process request and return response, then reset, for long-connection } }
void onConnection(const TcpConnectionPtr& conn) { if (conn->connected()) { connectionCount_.increment(); conn->setContext(ConnectionContext()); ConnectionContext* connectionContext = boost::any_cast<ConnectionContext>(conn->getMutableContext()); EntryPtr entry(new Entry(conn)); localConnectionBuckets_.get()->back().insert(entry); WeakEntryPtr weakEntry(entry); connectionContext->weakEntry_ = weakEntry; } else { connectionCount_.decrement(); const ConnectionContext& connectionContext = boost::any_cast<const ConnectionContext&>(conn->getContext()); const ConnectionSubscription& connSub = connectionContext.subscription_; // subtle: doUnsubscribe will erase *it, so increase before calling. for (auto it = connSub.begin(); it != connSub.end();) { doUnsubscribe(conn, *it++); } } }
void doUnsubscribe(const TcpConnectionPtr& conn, const string& topic) { getTopic(topic).remove(conn); ConnectionContext* connectionContext = boost::any_cast<ConnectionContext>(conn->getMutableContext()); connectionContext->subscription_.erase(topic); }
void doSubscribe(const TcpConnectionPtr& conn, const string& topic) { ConnectionContext* connectionContext = boost::any_cast<ConnectionContext>(conn->getMutableContext()); connectionContext->subscription_.insert(topic); getTopic(topic).add(conn); }