| 
									
										
										
										
											2024-05-27 10:35:06 +02:00
										 |  |  | //
 | 
					
						
							|  |  |  | // Copyright (c) 2023-2024 Ivica Siladic, Bruno Iljazovic, Korina Simicevic
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // Distributed under the Boost Software License, Version 1.0.
 | 
					
						
							|  |  |  | // (See accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-27 09:00:54 +01:00
										 |  |  | //[hello_world_over_websocket_tls
 | 
					
						
							|  |  |  | #include <iostream>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <boost/asio/io_context.hpp>
 | 
					
						
							|  |  |  | #include <boost/asio/detached.hpp>
 | 
					
						
							|  |  |  | #include <boost/asio/ssl.hpp>
 | 
					
						
							|  |  |  | #include <boost/asio/ip/tcp.hpp>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <boost/beast/websocket.hpp>
 | 
					
						
							| 
									
										
										
										
											2024-10-07 10:01:27 +02:00
										 |  |  | #include <boost/beast/ssl/ssl_stream.hpp> // async_teardown specialization for websocket ssl stream
 | 
					
						
							| 
									
										
										
										
											2024-02-27 09:00:54 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <async_mqtt5.hpp>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // External customization point.
 | 
					
						
							|  |  |  | namespace async_mqtt5 { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template <typename StreamBase> | 
					
						
							|  |  |  | struct tls_handshake_type<boost::asio::ssl::stream<StreamBase>> { | 
					
						
							|  |  |  | 	static constexpr auto client = boost::asio::ssl::stream_base::client; | 
					
						
							|  |  |  | 	static constexpr auto server = boost::asio::ssl::stream_base::server; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // This client uses this function to indicate which hostname it is
 | 
					
						
							|  |  |  | // attempting to connect to at the start of the handshaking process.
 | 
					
						
							|  |  |  | template <typename StreamBase> | 
					
						
							|  |  |  | void assign_tls_sni( | 
					
						
							|  |  |  | 	const authority_path& ap, | 
					
						
							| 
									
										
										
										
											2024-10-07 10:01:27 +02:00
										 |  |  | 	boost::asio::ssl::context& /*ctx*/, | 
					
						
							| 
									
										
										
										
											2024-02-27 09:00:54 +01:00
										 |  |  | 	boost::asio::ssl::stream<StreamBase>& stream | 
					
						
							|  |  |  | ) { | 
					
						
							|  |  |  | 	SSL_set_tlsext_host_name(stream.native_handle(), ap.host.c_str()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } // end namespace async_mqtt5
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // The certificate file in the PEM format.
 | 
					
						
							|  |  |  | constexpr char ca_cert[] = | 
					
						
							|  |  |  | "-----BEGIN CERTIFICATE-----\n" | 
					
						
							|  |  |  | "...........................\n" | 
					
						
							|  |  |  | "-----END CERTIFICATE-----\n" | 
					
						
							|  |  |  | ; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int main() { | 
					
						
							|  |  |  | 	boost::asio::io_context ioc; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Context satisfying ``__TlsContext__`` requirements that the underlying SSL stream will use.
 | 
					
						
							|  |  |  | 	// The purpose of the context is to allow us to set up TLS/SSL-related options. 
 | 
					
						
							|  |  |  | 	// See ``__SSL__`` for more information and options.
 | 
					
						
							|  |  |  | 	boost::asio::ssl::context context(boost::asio::ssl::context::tls_client); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	async_mqtt5::error_code ec; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Add the trusted certificate authority for performing verification.
 | 
					
						
							|  |  |  | 	context.add_certificate_authority(boost::asio::buffer(ca_cert), ec); | 
					
						
							|  |  |  | 	if (ec) | 
					
						
							|  |  |  | 		std::cout << "Failed to add certificate authority!" << std::endl; | 
					
						
							|  |  |  | 	ec.clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Set peer verification mode used by the context.
 | 
					
						
							|  |  |  | 	// This will verify that the server's certificate is valid and signed by a trusted certificate authority.
 | 
					
						
							|  |  |  | 	context.set_verify_mode(boost::asio::ssl::verify_peer, ec); | 
					
						
							|  |  |  | 	if (ec) | 
					
						
							|  |  |  | 		std::cout << "Failed to set peer verification mode!" << std::endl; | 
					
						
							|  |  |  | 	ec.clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-24 14:03:18 +02:00
										 |  |  | 	// Construct the Client with WebSocket/SSL as the underlying stream 
 | 
					
						
							|  |  |  | 	// with ``__SSL_CONTEXT__`` as the ``__TlsContext__`` type.
 | 
					
						
							| 
									
										
										
										
											2024-02-27 09:00:54 +01:00
										 |  |  | 	async_mqtt5::mqtt_client< | 
					
						
							|  |  |  | 		boost::beast::websocket::stream<boost::asio::ssl::stream<boost::asio::ip::tcp::socket>>, | 
					
						
							|  |  |  | 		boost::asio::ssl::context | 
					
						
							|  |  |  | 	> client(ioc, std::move(context)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// 8884 is the default Websocket/TLS MQTT port.
 | 
					
						
							| 
									
										
										
										
											2024-10-08 13:27:28 +02:00
										 |  |  | 	client.brokers("<your-mqtt-broker-path>", 8884) // Path example: localhost/mqtt
 | 
					
						
							| 
									
										
										
										
											2024-02-27 09:00:54 +01:00
										 |  |  | 		.async_run(boost::asio::detached); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	client.async_publish<async_mqtt5::qos_e::at_most_once>( | 
					
						
							|  |  |  | 		"<topic>", "Hello world!", | 
					
						
							|  |  |  | 		async_mqtt5::retain_e::no, async_mqtt5::publish_props{}, | 
					
						
							|  |  |  | 		[&client](async_mqtt5::error_code ec) { | 
					
						
							|  |  |  | 			std::cout << ec.message() << std::endl; | 
					
						
							|  |  |  | 			client.async_disconnect(boost::asio::detached); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ioc.run(); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2024-04-24 14:03:18 +02:00
										 |  |  | //]
 |