应用层如何管理 websocketpp 的连接句柄 (connection hdl)?

2년 전

用过 websocketpp 的同学都知道, 应用程序需要自己保存各个客户端的连接句柄, 这个动作一般是在连接打开后, 在 on_open 回调中将句柄加入自己的容器中, 然后在 on_close 回调中将句柄移除. 问题就在于这里选用什么容器.

一开始会想这还不简单, 无非就是 vector, set, map 嘛, connection hdl 这种东西用 vector 就行了!

这里用 vector 的话, 添加句柄没问题, 然而移除句柄却并没有想象的那么直接, 最初我在 on_close 中是这样写的:

void rpcd::on_close(websocket_asio_server* s, websocketpp::connection_hdl hdl) {
  conn_hdls.erase(std::remove(std::begin(conn_hdls), std::end(conn_hdls), hdl));
}

结果显然, 连编译都过不了, 原因是 vector 要移除数据得先靠比较操作找到值相同的元素, 获得其迭代器交给 erase 去移除. 然而 websocketpp::connection_hdl 是个 weak_ptr, 就没定义比较操作运算符, 所以无法比较.

所以这里得自己定义比较方式, 我们知道通过 weak_ptr.lock() 可以获得它所共享的 shared_ptr 的值, 那上面代码就可以改成这样了:

void rpcd::on_close(websocket_asio_server* s, websocketpp::connection_hdl hdl) {
  conn_hdls.erase(std::remove_if(std::begin(conn_hdls), std::end(conn_hdls),
                                 [&](const websocketpp::connection_hdl& a) {
                                   if (a.lock() == hdl.lock()) return true;
                                   return false;
                                 }));
}

这里有个小细节是当连接断开时, connection_hdl 会被释放, 届时 a.lock() 会返回 nullptr. 但是经过验证证明在 on_close 时是还没有释放的, 而且就算释放了, 对这段代码也没有影响.

Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!
STEEMKR.COM IS SPONSORED BY
ADVERTISEMENT