JSON-RPC 2.0
JSON-RPC 2.0 Modern C++ Library
Loading...
Searching...
No Matches
pipe_transport.cpp
Go to the documentation of this file.
2
3#include <stdexcept>
4#include <unistd.h>
5
6#include <spdlog/spdlog.h>
7
8namespace jsonrpc::transport {
9
10PipeTransport::PipeTransport(const std::string &socket_path, bool is_server)
11 : socket_(io_context_), socket_path_(socket_path), is_server_(is_server) {
12 spdlog::info(
13 "Initializing PipeTransport with socket path: {}. IsServer: {}",
14 socket_path, is_server);
15
16 if (is_server_) {
17 RemoveExistingSocketFile();
18 BindAndListen();
19 } else {
20 Connect();
21 }
22}
23
24auto PipeTransport::GetSocket() -> asio::local::stream_protocol::socket & {
25 return socket_;
26}
27
29 spdlog::info("Closing socket and shutting down PipeTransport.");
30 socket_.close();
31 io_context_.stop();
32}
33
34void PipeTransport::RemoveExistingSocketFile() {
35 if (unlink(socket_path_.c_str()) == 0) {
36 spdlog::info("Removed existing socket file: {}", socket_path_);
37 } else if (errno != ENOENT) {
38 spdlog::error(
39 "Failed to remove existing socket file: {}. Error: {}", socket_path_,
40 strerror(errno));
41 throw std::runtime_error("Failed to remove existing socket file.");
42 }
43}
44
45void PipeTransport::Connect() {
46 try {
47 asio::local::stream_protocol::endpoint endpoint(socket_path_);
48 socket_.connect(endpoint);
49 spdlog::info("Connected to socket at path: {}", socket_path_);
50 } catch (const std::exception &e) {
51 spdlog::error("Error connecting to socket: {}", e.what());
52 throw std::runtime_error("Error connecting to socket");
53 }
54}
55
56void PipeTransport::BindAndListen() {
57 try {
58 asio::local::stream_protocol::acceptor acceptor(
59 io_context_, asio::local::stream_protocol::endpoint(socket_path_));
60 acceptor.listen();
61 spdlog::info("Listening on socket path: {}", socket_path_);
62 acceptor.accept(socket_);
63 spdlog::info("Accepted connection on socket path: {}", socket_path_);
64 } catch (const std::exception &e) {
65 spdlog::error("Error binding/listening on socket: {}", e.what());
66 throw std::runtime_error("Error binding/listening on socket");
67 }
68}
69
70void PipeTransport::SendMessage(const std::string &message) {
71 try {
72 std::string full_message = message + "\n";
73 asio::write(socket_, asio::buffer(full_message));
74 spdlog::debug("Sent message: {}", message);
75 } catch (const std::exception &e) {
76 spdlog::error("Error sending message: {}", e.what());
77 throw std::runtime_error("Error sending message");
78 }
79}
80
81auto PipeTransport::ReceiveMessage() -> std::string {
82 try {
83 asio::streambuf buffer;
84 asio::read_until(socket_, buffer, '\n');
85 std::istream is(&buffer);
86 std::string message;
87 std::getline(is, message);
88 spdlog::debug("Received message: {}", message);
89 return message;
90 } catch (const std::exception &e) {
91 spdlog::error("Error receiving message: {}", e.what());
92 socket_.close();
93 throw std::runtime_error("Error receiving message");
94 }
95}
96
97} // namespace jsonrpc::transport
void SendMessage(const std::string &message) override
Sends a message in string to the transport layer.
auto GetSocket() -> asio::local::stream_protocol::socket &
PipeTransport(const std::string &socket_path, bool is_server)
Constructs a PipeTransport.
auto ReceiveMessage() -> std::string override
Receives a message from the transport layer.