Skip to content
Takatoshi Kondo edited this page Oct 20, 2022 · 1 revision

Customize socket

mqtt_cpp clients have a series of connect() and async_connect() function. Some of them have std::shared_ptr<Socket>&& socket parameter as the first parameter.

You can pass your customized socket to these functions. mqtt_cpp use it instead of internal generation.

One typical usecase is connecting to TLS-SNI required server. See https://github.com/redboltz/mqtt_cpp/blob/master/example/tls_client_with_sni.cpp

In order to connect to a TLS-SNI server, you need to call SSL_set_tlsext_host_name() OpenSSL API. That is customize. So you need to create custom socket (stream) shared_ptr. And then use it.

    // Create TLS client
    auto c = MQTT_NS::make_tls_sync_client(ioc, host, port);

    auto connect =
        [&] {
            // create custom socket
            auto stream =
                std::make_shared<
                    MQTT_NS::tcp_endpoint<
                        MQTT_NS::tls::stream<boost::asio::ip::tcp::socket>,
                        MQTT_NS::strand
                    >
            >(ioc, c->get_ssl_context());

            if (!SSL_set_tlsext_host_name(MQTT_NS::any_cast<SSL*>(stream->native_handle()), host.c_str())) {
                std::cout << "SSL_set_tlsext_host_name return false" << std::endl;
                return false;
            }
            c->connect(MQTT_NS::force_move(stream));
            return true;
        };

Here is the list of typical Socket type.

TCP

MQTT_NS::tcp_endpoint<
    boost::asio::ip::tcp::socket,
    MQTT_NS::strand
>

TLS

MQTT_NS::tcp_endpoint<
    MQTT_NS::tls::stream<boost::asio::ip::tcp::socket>,
    MQTT_NS::strand
>

WS

MQTT_NS::ws_endpoint<
    boost::asio::ip::tcp::socket,
    MQTT_NS::strand
>

WS on TLS (WSS)

MQTT_NS::ws_endpoint<
    MQTT_NS::tls::stream<boost::asio::ip::tcp::socket>,
    MQTT_NS::strand
>

Type matching is very important. You need to use the correct type's shared_ptr. connect() and async_connect() have overloads that take MQTT_NS::any as the first parameter. If you pass a wrong type variable, then no compile error reported. Your variable is matched to the MQTT_NS::any overload. So the customized socket is not used. Instead of that, internally generated socket is used.