带有 SSL 的 Boost.Beast WebSocket:正确初始化需要多个 async_handshake 调用?

问题描述 投票:0回答:1

我在尝试使用 Boost.Beast 和 Boost.Asio 与 SSL 建立 WebSocket 连接时遇到问题。 WebSocket 连接似乎仅当我在野兽::websocket::stream 和 SSL next_layer() 上调用 async_handshake 时才起作用。

// Relevant part of the code
class WebSocketClient : public std::enable_shared_from_this<WebSocketClient> {
public:
    // ... (other members)

    void onConnect(const boost::system::error_code& ec, const tcp::endpoint&) {
        if (!ec) {
            // WebSocket initialization
            ws_ = beast::websocket::stream<ssl::stream<beast::tcp_stream>>(io_context_, ssl_context_);

            // This version works for me, but is it correct?
            ws_.next_layer().async_handshake(ssl::stream_base::client, std::bind(&WebSocketClient::onSslHandshake, shared_from_this(), std::placeholders::_1));
            
            // Perform WebSocket handshake asynchronously
            ws_.async_handshake(host_, target_, "/", std::bind(&WebSocketClient::onHandshake, shared_from_this(), std::placeholders::_1));
        } else {
            std::cerr << "Connection error: " << ec.message() << std::endl;
        }
    }
    // ... (other methods)
private:
    asio::io_context& io_context_;
    ssl::context& ssl_context_;
    beast::websocket::stream<ssl::stream<beast::tcp_stream>> ws_;
    std::string host_;
    std::string target_;

    // ... (other members)
};

在这种情况下,在野兽::websocket::stream和SSL next_layer()上调用async_handshake是否正常?它似乎有效,但我想确保我遵循正确且标准的方法,使用 Boost.Beast 与 SSL 建立 WebSocket 连接。

如果我只在 ws 上使用握手,我会得到:未初始化(SSL 例程)

任何见解或建议将不胜感激!

c++ websocket boost boost-beast
1个回答
0
投票

你没有问题。

您特别声明您同时使用 Websocket 和 SSL。

两种协议都需要握手。因为 SSL 是较低层,所以它是第一位的。在您的代码中甚至明确表明它是较低层:

ws_.next_layer()
不是Websocket层,它是SSL层。

它们是不同的协议和不同的握手,并且两者都是必需的,因为您想使用它们。


请注意,您没有抱怨连接,这是又一层:

 ws_.next_layer().next_layer().async_connect(...)

其实情况是一样的,唯一的区别就是函数的名称。然而,在

TCP
层面上,它很大程度上涉及另一次握手(https://en.wikipedia.org/wiki/Handshake_(computing)https://www.geeksforgeeks.org/tcp- 3次握手过程/)


注意

您的代码已损坏,因为它“并行”进行了两次握手。今天可能会起作用,但唯一可靠的方法是在 SSL 握手完成后启动 Websocket 握手,例如在

onSslHandshake

© www.soinside.com 2019 - 2024. All rights reserved.