15#include <boost/asio/connect.hpp>
16#include <boost/asio/post.hpp>
17#include <boost/asio/read.hpp>
18#include <boost/asio/write.hpp>
19#include <boost/asio/bind_executor.hpp>
40 return boost::asio::buffer(&
_size,
sizeof(
_size));
43 boost::asio::mutable_buffer
buffer() {
69 boost::asio::io_context &io_context,
73 std::string(
"tcp client ") +
std::to_string(token.get_stream_id())),
75 _callback(
std::move(callback)),
78 _connection_timer(io_context),
81 throw_exception(std::invalid_argument(
"invalid token, only TCP tokens supported"));
88 auto self = shared_from_this();
93 using boost::system::error_code;
103 auto handle_connect = [
this, self, ep](error_code ec) {
110 _socket.set_option(boost::asio::ip::tcp::no_delay(
true));
111 log_debug(
"streaming client: connected to", ep);
114 log_debug(
"streaming client: sending stream id", stream_id);
115 boost::asio::async_write(
117 boost::asio::buffer(&stream_id,
sizeof(stream_id)),
118 boost::asio::bind_executor(
_strand, [=](error_code ec,
size_t DEBUG_ONLY(bytes)) {
129 log_debug(
"streaming client: failed to send stream id:", ec.message());
134 log_info(
"streaming client: connection failed:", ec.message());
139 log_debug(
"streaming client: connecting to", ep);
140 _socket.async_connect(ep, boost::asio::bind_executor(
_strand, handle_connect));
145 auto self = shared_from_this();
152 boost::asio::post(
_strand, [
this, self]() {
161 auto self = shared_from_this();
171 auto self = shared_from_this();
178 auto message = std::make_shared<IncomingMessage>(
_buffer_pool->Pop());
180 auto handle_read_data = [
this, self, message](boost::system::error_code ec,
size_t DEBUG_ONLY(bytes)) {
181 DEBUG_ONLY(
log_debug(
"streaming client: Client::ReadData.handle_read_data", bytes,
"bytes"));
199#ifndef LIBCARLA_NO_EXCEPTIONS
203#ifndef LIBCARLA_NO_EXCEPTIONS
204 }
catch (
const std::exception &e) {
205 log_error(
"streaming client: exception in stream callback:", e.what());
211 log_debug(
"streaming client: failed to read data:", ec.message());
216 auto handle_read_header = [
this, self, message, handle_read_data](
217 boost::system::error_code ec,
219 DEBUG_ONLY(
log_debug(
"streaming client: Client::ReadData.handle_read_header", bytes,
"bytes"));
220 if (!ec && (message->size() > 0u)) {
227 boost::asio::async_read(
230 boost::asio::bind_executor(
_strand, handle_read_data));
232 log_debug(
"streaming client: failed to read header:", ec.message());
240 boost::asio::async_read(
242 message->size_as_buffer(),
243 boost::asio::bind_executor(
_strand, handle_read_header));
#define DEBUG_ASSERT(predicate)
#define DEBUG_ASSERT_EQ(lhs, rhs)
#define DEBUG_ASSERT_NE(lhs, rhs)
#define LIBCARLA_INITIALIZE_LIFETIME_PROFILER(display_name)
void reset(size_type size)
Reset the size of this buffer.
boost::asio::const_buffer buffer() const noexcept
Make a boost::asio::buffer from this buffer.
boost::asio::io_context::strand _strand
callback_function_type _callback
std::function< void(Buffer)> callback_function_type
std::shared_ptr< BufferPool > _buffer_pool
boost::asio::ip::tcp::socket _socket
boost::asio::steady_timer _connection_timer
Helper for reading incoming TCP messages.
IncomingMessage(Buffer &&buffer)
boost::asio::mutable_buffer size_as_buffer()
boost::asio::mutable_buffer buffer()
Serializes a stream endpoint.
boost::asio::ip::tcp::endpoint to_tcp_endpoint() const
const auto & get_stream_id() const
bool protocol_is_tcp() const
static time_duration seconds(size_t timeout)
uint32_t message_size_type
This file contains definitions of common data structures used in traffic manager.
static void log_error(Args &&... args)
static void log_info(Args &&... args)
void throw_exception(const ExceptionT &e)
Templated on the static type so the thrown object keeps its dynamic type: taking a const std::excepti...
static void log_debug(Args &&... args)