【问题标题】:boost beast websocket connection close handler提升野兽 websocket 连接关闭处理程序
【发布时间】:2018-06-20 19:08:38
【问题描述】:

我是 boost 新手,我正在尝试为 websocket 编写一个简单的聊天应用程序。作为参考,我使用了网站上的 websocket-server-sync 示例。

我创建了一个全局向量来存储 websocket::streams,并在创建 websocket 后的 do_session 方法中将其推送到向量中。

std::vector<websocket::stream<tcp::socket>*> socket_streams;

每次我读到一条消息时,我都会从这个向量发送给每个人,所以到目前为止它运行良好。但是,当有人关闭连接时(即使它没有正确关闭,例如互联网连接断开),我想从我的向量中删除流对象。我试图在野兽头中寻找“关闭处理程序”或类似的东西,但我找不到任何东西。有没有办法做到这一点?喜欢:

void close_handler(websocket::stream<tcp::socket>* _stream) 
{
   //remove _stream from socket_streams
}

【问题讨论】:

  • 我不明白,这是同步通信,所以在退出函数之前将其从向量中删除。还要记住在全局上使用互斥,写入可能会失败,因为套接字已经关闭。
  • 感谢您的回复!是的,这是同步通信,但函数本身是一个无限循环,正如您在 boost 示例中所见。但是当客户端断开连接时,我的向量元素仍然存在,每当其他人写东西时,我都会尝试将消息发送给他。我相信它会导致异常,因为连接已关闭。所以为避免这种情况,当有人断开连接时,我想从我的向量中删除向量元素。很抱歉,如果我说错了或者不太清楚。

标签: c++ boost websocket beast


【解决方案1】:

据我了解,您的问题是在 try/catch 子句之外延长流的生命周期。

保持构造函数可以抛出的假设,您可以在 try 中使用复制构造函数:

void do_session(tcp::socket& socket)
{
    websocket::stream<tcp::socket> ws;
    try
    {
        ws = std::move(websocket::stream<tcp::socket>>(std::move(socket)));
        add_socket(&ws);
        // ....
    }
    catch(boost::system::system_error const& se) { ... }
    catch(std::exception const& e) {}

    erase_socket_if_exists(&ws);
}

如果移动分配不存在,您可以使用 std::uniq_ptr。

请注意,您无法避免尝试写入关闭流的竞争条件。这就是为什么您必须处理写入引发异常的情况。

还要注意,在你的方案中,你必须持有容器的锁,直到你完成对所有套接字的写入。

【讨论】:

    猜你喜欢
    • 2019-06-04
    • 1970-01-01
    • 2020-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多