JSON-RPC 2.0
JSON-RPC 2.0 Modern C++ Library
Loading...
Searching...
No Matches
framed_socket_transport.cpp
Go to the documentation of this file.
2
3#include <stdexcept>
4#include <unistd.h>
5
6#include <fmt/format.h>
7#include <spdlog/spdlog.h>
8
9namespace jsonrpc::transport {
10
12 const std::string &host, uint16_t port, bool is_server)
13 : SocketTransport(host, port, is_server), FramedTransport() {
14 spdlog::info(
15 "FramedSocketTransport initialized with host: {} and port: {}", host,
16 port);
17}
18
19void FramedSocketTransport::SendMessage(const std::string &message) {
20 try {
21 asio::streambuf message_buf;
22 std::ostream message_stream(&message_buf);
23 FrameMessage(message_stream, message);
24
25 asio::error_code ec;
26 std::size_t bytes_written =
27 asio::write(GetSocket(), message_buf.data(), ec);
28
29 if (ec) {
30 throw std::runtime_error("Error sending message: " + ec.message());
31 }
32
33 spdlog::info(
34 "FramedSocketTransport sent message with {} bytes", bytes_written);
35 } catch (const std::exception &e) {
36 spdlog::error("FramedSocketTransport failed to send message: {}", e.what());
37 throw;
38 }
39}
40
42 asio::streambuf buffer;
43 asio::error_code ec;
44
45 // Read headers until \r\n\r\n delimiter
46 asio::read_until(GetSocket(), buffer, kHeaderDelimiter, ec);
47 if (ec) {
48 throw std::runtime_error("Failed to read message headers: " + ec.message());
49 }
50
51 std::istream header_stream(&buffer);
52
53 // Extract content length from the headers
54 int content_length = ReadContentLengthFromStream(header_stream);
55
56 // Calculate how much more content we need to read
57 std::size_t remaining_content_length = content_length - buffer.size();
58
59 // Read any remaining content directly into the buffer
60 if (remaining_content_length > 0) {
61 asio::read(GetSocket(), buffer.prepare(remaining_content_length), ec);
62 if (ec && ec != asio::error::eof) {
63 throw std::runtime_error(
64 "Failed to read message content: " + ec.message());
65 }
66 buffer.commit(remaining_content_length);
67 }
68
69 // Convert the entire buffer to a string
70 std::string content(
71 asio::buffers_begin(buffer.data()), asio::buffers_end(buffer.data()));
72 return content;
73}
74
75} // namespace jsonrpc::transport
auto ReceiveMessage() -> std::string override
Receives a message from the transport layer.
void SendMessage(const std::string &message) override
Sends a message in string to the transport layer.
FramedSocketTransport(const std::string &host, uint16_t port, bool is_server)
Base class for framed transport mechanisms.
static void FrameMessage(std::ostream &output, const std::string &message)
Constructs a framed message.
Transport implementation using TCP/IP sockets.
auto GetSocket() -> asio::ip::tcp::socket &