1

我正在尝试编写一个 https flex 服务器,它可以根据升级请求升级到 websocket。https 类进行 ssl 握手std::shared_ptr<boost::beast::ssl_stream<boost::beast::tcp_stream>> m_ptls_stream

现在我需要将此流传输到 websocket 类并将其转换为类型

std::shared_ptr<boost::beast::websocket::stream<
        boost::beast::ssl_stream<boost::beast::tcp_stream>>>

但是由于某种原因,websocket 流的构造函数不接受共享指针,并且我无法取消引用 ssl_stream shared_ptr,因为我得到了复制构造函数被删除的错误

严重性代码描述项目文件行抑制状态错误 C2280 'boost::beast::ssl_streamboost::beast::tcp_stream::ssl_stream(const boost::beast::ssl_streamboost::beast::tcp_stream &)':试图引用一个删除功能 D:\Work\remote_pc\out\build\x64-Debug\remote_pc D:\Work\boost_1_73_0\boost\asio\impl\executor.hpp 218

void async_ws_client::add_stream(std::shared_ptr<boost::beast::ssl_stream<boost::beast::tcp_stream>>&& ptls_stream)
{   
    if (m_ptls_context)
    {       
        m_p_wss_stream = std::make_shared<
            boost::beast::websocket::stream<
            boost::beast::ssl_stream<
            boost::beast::tcp_stream>>>(std::move(*ptls_stream), *m_ptls_context);
    }
}

感觉就像我错过了一些东西,几天都无法弄清楚。请帮忙..!!

另外,如果我这样做

m_p_wss_stream = std::make_shared<
                boost::beast::websocket::stream<
                boost::beast::ssl_stream<
                boost::beast::tcp_stream>>>(std::move(ptls_stream->next_layer()),
                    *m_ptls_context);

套接字抛出错误:当我在创建它后对流执行 async_accept() 时未初始化。

4

2 回答 2

0

取消引用工作。只是你不能从你传递的参数构造你想要的类型。

简化您的代码,使其变得可读和独立:

住在科利鲁

#include <boost/beast.hpp>
#include <boost/beast/ssl.hpp>
#include <boost/beast/websocket.hpp>
#include <boost/asio.hpp>

namespace net   = boost::asio;
namespace beast = boost::beast;
namespace ws    = beast::websocket;
namespace ssl   = net::ssl;

struct async_ws_client {
    using tcp_stream = beast::tcp_stream;
    using ssl_stream = beast::ssl_stream<tcp_stream>;

    void add_stream(std::shared_ptr<ws::stream<tcp_stream>> ptls_stream)
    {
        if (m_ptls_context) {
            m_p_wss_stream = std::make_shared<ws::stream<ssl_stream>>(
                std::move(*ptls_stream), *m_ptls_context);
        }
    }

    std::shared_ptr<ws::stream<tcp_stream>> m_p_tls_stream;
    std::shared_ptr<ssl::context>           m_ptls_context;
    std::shared_ptr<ws::stream<ssl_stream>> m_p_wss_stream;
};

int main() {
}

错误小说将消息隐藏在 shared_ptr 构造转发机制的深处。但是,等效的、更简单的代码也不会编译,原因相同:

住在科利鲁

struct simple_async_ws_client {
    using tcp_stream = beast::tcp_stream;
    using ssl_stream = beast::ssl_stream<tcp_stream>;

    void add_stream(ws::stream<tcp_stream>&& tls_stream) {
        m_wss_stream.emplace(std::move(tls_stream), m_tls_context);
    }

    net::io_context        m_io;
    ws::stream<tcp_stream> m_tls_stream{m_io};

    ssl::context                          m_tls_context;
    std::optional<ws::stream<ssl_stream>> m_wss_stream;
};

快速浏览一下您的链接告诉我应该更像:Live On Coliru

    m_wss_stream.emplace(tls_stream.next_layer().release_socket(),
                         m_tls_context);

现在,您可以将其转换回完全 shared_ptr-overgrown 版本的代码:

struct async_ws_client {
    using tcp_stream = beast::tcp_stream;
    using ssl_stream = beast::ssl_stream<tcp_stream>;

    void add_stream(std::shared_ptr<ws::stream<tcp_stream>> const& p_tls_stream)
    {
        if (m_p_tls_context) {
            m_p_wss_stream = std::make_shared<ws::stream<ssl_stream>>(
                p_tls_stream->next_layer().release_socket(), *m_p_tls_context);
        }
    }

    std::shared_ptr<ws::stream<tcp_stream>> m_p_tls_stream;

    std::shared_ptr<ssl::context>           m_p_tls_context;
    std::shared_ptr<ws::stream<ssl_stream>> m_p_wss_stream;
};

请注意,尽管(ab)以这种规模使用共享指针有点反模式。您可能应该考虑unique_ptror optional(对于惰性构造类型),或者实际上enable_shared_from_this对于整个类,因此所有成员通过扩展共享所有权。这也用于链接的文档示例。

于 2021-09-03T00:31:21.790 回答
0

在理解上犯了一个愚蠢的错误,无法将 tls_context 传递给 websocket::stream 构造函数。以下代码有效

void async_ws_client::add_stream(
std::shared_ptr<boost::beast::ssl_stream<boost::beast::tcp_stream>>&& ptls_stream)
    {           
        if (m_ptls_context)
        {
            m_p_wss_stream = std::make_shared<
                boost::beast::websocket::stream<
                boost::beast::ssl_stream<
                boost::beast::tcp_stream>>>(std::move(*ptls_stream));
         }
    }
于 2021-09-03T01:17:56.437 回答