踢掉超时连接

说明:

TcpServer.cc中客户端来一个连接的时候执行下面操作

TcpConnectionPtr conn(newTcpConnection(ioLoop,

                                         connName,

                                         sockfd,

                                         localAddr,

                                          peerAddr));

connections_[connName] = conn;

conn->setConnectionCallback(connectionCallback_);

conn->setMessageCallback(messageCallback_);

conn->setWriteCompleteCallback(writeCompleteCallback_);

conn->setCloseCallback(

boost::bind(&TcpServer::removeConnection,this, _1)); // FIXME: unsafe

 ioLoop->runInLoop(boost::bind(&TcpConnection::connectEstablished,conn));

 

即客户连接时候会调用TcpConnection::connectEstablished,该函数中会调用connectionCallback;

客户端关闭时候会调用TcpConnection::setConnectionCallback和 TcpConnection::setCloseCallback

 

 

typedef boost::weak_ptr<muduo::net::TcpConnection>WeakTcpConnectionPtr;

 

 struct Entry : public muduo::copyable

  {

   /*初始化时候获得muduo::net::TcpConnection类型对象的弱指针*/

   explicit Entry(const WeakTcpConnectionPtr& weakConn)

     : weakConn_(weakConn)

    {

    }

      

       /*析构时候将弱指针提升为强指针,提升成功则关闭写端*/

   ~Entry()

    {

     muduo::net::TcpConnectionPtr conn = weakConn_.lock();

     if (conn)

     {

       conn->shutdown();

     }

    }

 

   WeakTcpConnectionPtr weakConn_;

  };

  typedefboost::shared_ptr<TcpConnection> TcpConnectionPtr;

 typedef boost::shared_ptr<Entry> EntryPtr;

 typedef boost::weak_ptr<Entry> WeakEntryPtr;

 typedef boost::unordered_set<EntryPtr>Bucket;

 typedef boost::circular_buffer<Bucket>WeakConnectionList;

  WeakConnectionListconnectionBuckets_; //存放连接的强指针

 

connectionBuckets是个循环队列,当往队尾插入一个元素空的Bucket时候,队头就会被删掉,此时队头的Bucket中每个EntryPtr的引用计数均会-1的,当该EntryPtr的引用计数值为0时候就会调用Entry对象的析构函数的。

 

说明:

最初connectionBuckets_.resize(idleSeconds);

当客户端连接上时候,客户的conn为TcpConnectionPtr;

EntryPtr entry(new Entry(conn));                     //让强引用计数+1

connectionBuckets_.back().insert(entry);   //将该强引用指针放入Bucket的末尾的set中

WeakEntryPtr weakEntry(entry);                //将弱指针保存在conn中,如果将强指针存于conn                                                            中则永远删不掉的

conn->setContext(weakEntry);

 

当收到客户端消息时候,

WeakEntryPtrweakEntry(boost::any_cast<WeakEntryPtr>(conn->getContext()));

EntryPtr entry(weakEntry.lock());

if (entry)

{

   connectionBuckets_.back().insert(entry);

}

 

由于定时器1s会执行一次:

connectionBuckets_.push_back(Bucket());

这样会将队列的头部Bucket给弹出去的,即该Bucket中的每一个强引用计数-1,当减为0时候即调用~Entry(),这里面可以直接conn->shutdown();或者conn-> handleClose();

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值