16#include <boost/asio/read.hpp>
17#include <boost/asio/write.hpp>
18#include <boost/asio/bind_executor.hpp>
19#include <boost/asio/post.hpp>
31 boost::asio::io_context &io_context,
40 _deadline(io_context,
std::chrono::steady_clock::time_point::max()),
46 boost::system::error_code ec;
47 _socket.shutdown(boost::asio::socket_base::shutdown_both, ec);
60 const boost::asio::ip::tcp::no_delay option(
true);
67 on_opened(shared_from_this());
72 void Primary::Write(std::shared_ptr<const carla::streaming::detail::tcp::Message> message) {
75 std::weak_ptr<Primary> weak = shared_from_this();
76 boost::asio::post(
_strand, [weak, message]() {
77 auto self = weak.lock();
79 if (!self->_socket.is_open()) {
82 self->_write_queue.push_back(message);
83 if (!self->_is_writing) {
97 std::weak_ptr<Primary> weak = shared_from_this();
98 auto handle_sent = [weak, message](
const boost::system::error_code &ec, size_t) {
99 auto self = weak.lock();
102 self->_write_queue.clear();
103 self->_is_writing =
false;
107 if (self->_socket.is_open()) {
108 log_error(
"session ", self->_session_id,
": error sending data: ", ec.message());
113 self->_write_queue.pop_front();
118 boost::asio::async_write(
120 message->GetBufferSequence(),
121 boost::asio::bind_executor(
_strand, handle_sent));
126 Buffer buffer(
reinterpret_cast<const unsigned char *
>(text.data()), text.size());
131 std::weak_ptr<Primary> weak = shared_from_this();
132 boost::asio::post(
_strand, [weak]() {
133 auto self = weak.lock();
136 auto message = std::make_shared<IncomingMessage>(self->_buffer_pool->Pop());
138 auto handle_read_data = [weak, message](boost::system::error_code ec,
size_t DEBUG_ONLY(bytes)) {
139 auto self = weak.lock();
146 self->_on_response(self, message->pop());
147 std::cout <<
"Getting data on listener\n";
151 log_error(
"primary server: failed to read data: ", ec.message());
155 auto handle_read_header = [weak, message, handle_read_data](
156 boost::system::error_code ec,
158 auto self = weak.lock();
161 log_error(
"primary server: secondary announced a", message->size(),
162 "byte message, larger than any valid one; closing the session");
164 }
else if (!ec && (message->size() > 0u)) {
167 boost::asio::async_read(
170 boost::asio::bind_executor(self->_strand, handle_read_data));
173 log_error(
"Primary server: failed to read header: ", ec.message());
181 boost::asio::async_read(
183 message->size_as_buffer(),
184 boost::asio::bind_executor(self->_strand, handle_read_header));
189 std::weak_ptr<Primary> weak = shared_from_this();
190 boost::asio::post(
_strand, [weak]() {
191 auto self = weak.lock();
198 if (
_deadline.expiry() <= std::chrono::steady_clock::now()) {
202 std::weak_ptr<Primary> weak = shared_from_this();
203 _deadline.async_wait([weak](boost::system::error_code ec) {
204 auto self = weak.lock();
209 log_error(
"session ", self->_session_id,
" timed out error: ", ec.message());
220 boost::system::error_code ec2;
221 _socket.shutdown(boost::asio::socket_base::shutdown_both, ec2);
#define DEBUG_ASSERT(predicate)
#define DEBUG_ASSERT_EQ(lhs, rhs)
#define DEBUG_ASSERT_NE(lhs, rhs)
#define LIBCARLA_INITIALIZE_LIFETIME_PROFILER(display_name)
static std::shared_ptr< BufferView > CreateFrom(Buffer &&buffer)
std::function< void(std::shared_ptr< Primary >)> callback_function_type
std::function< void(std::shared_ptr< Primary >, carla::Buffer)> callback_function_type_response
std::deque< message_type > _write_queue
Messages waiting to be written, oldest first, and whether one is being written.
void WriteNext()
Starts writing the front of the write queue. Strand only.
std::shared_ptr< const carla::streaming::detail::tcp::Message > message_type
void Open(Listener::callback_function_type on_opened, Listener::callback_function_type on_closed, Listener::callback_function_type_response on_response)
Starts the session and calls on_opened after successfully reading the stream id, and on_closed once t...
Listener::callback_function_type _on_closed
Primary(boost::asio::io_context &io_context, time_duration timeout, Listener &server)
boost::asio::io_context::strand _strand
static auto MakeMessage(Buffers... buffers)
Listener::callback_function_type_response _on_response
boost::asio::steady_timer _deadline
void Write(std::shared_ptr< const carla::streaming::detail::tcp::Message > message)
Writes some data to the socket.
void CloseNow(boost::system::error_code ec=boost::system::error_code())
void Close()
Post a job to close the session.
Positive time duration up to milliseconds resolution.
constexpr auto to_chrono() const
void EnableKeepAlive(boost::asio::ip::tcp::socket &socket)
Lets either end notice a peer that vanished without closing the connection (a killed host,...
constexpr std::size_t kMaxMultiGpuMessageBytes
Largest message either end accepts: a frame (capped at 1 GiB by the primary) plus room for its header...
static std::atomic_size_t SESSION_COUNTER
This file contains definitions of common data structures used in traffic manager.
static void log_error(Args &&... args)
static void log_debug(Args &&... args)