OSSIA
Open Scenario System for Interactive Application
Loading...
Searching...
No Matches
tcp_socket.hpp
1#pragma once
2#include <ossia/network/context.hpp>
3#include <ossia/network/sockets/configuration.hpp>
4
5#include <boost/asio/io_context.hpp>
6#include <boost/asio/ip/tcp.hpp>
7#include <boost/asio/ip/udp.hpp>
8#include <boost/asio/local/datagram_protocol.hpp>
9#include <boost/asio/placeholders.hpp>
10#include <boost/asio/strand.hpp>
11#include <boost/asio/write.hpp>
12
13#include <nano_signal_slot.hpp>
14
15namespace ossia::net
16{
17class tcp_listener
18{
19public:
20 using proto = boost::asio::ip::tcp;
21 using socket = typename proto::socket;
22
23 tcp_listener() = delete;
24 tcp_listener(const tcp_listener&) = delete;
25 tcp_listener& operator=(const tcp_listener&) = delete;
26 tcp_listener(tcp_listener&&) = default;
27 tcp_listener& operator=(tcp_listener&&) = default;
28 explicit tcp_listener(proto::socket sock)
29 : m_socket{std::move(sock)}
30 {
31 }
32
33 void close() { m_socket.close(); }
34
35 void write(const boost::asio::const_buffer& buf) { boost::asio::write(m_socket, buf); }
36
37 void on_close() { }
38
39 void on_fail() { }
40
41 proto::socket m_socket;
42};
43
44class tcp_server
45{
46public:
47 using proto = boost::asio::ip::tcp;
48 using socket = typename proto::socket;
49 using listener = tcp_listener;
50
51 tcp_server(const inbound_socket_configuration& conf, boost::asio::io_context& ctx)
52 : m_context{ctx}
53 , m_acceptor{
54 boost::asio::make_strand(ctx),
55 proto::endpoint{boost::asio::ip::make_address(conf.bind), conf.port}}
56 {
57 }
58
59 tcp_server(
60 const inbound_socket_configuration& conf, ossia::net::network_context_ptr ctx)
61 : tcp_server{conf, ctx->context}
62 {
63 }
64
65 boost::asio::io_context& m_context;
66 proto::acceptor m_acceptor;
67};
68
69class tcp_client
70{
71public:
72 using proto = boost::asio::ip::tcp;
73 using socket = typename proto::socket;
74
75 tcp_client(const outbound_socket_configuration& conf, boost::asio::io_context& ctx)
76 : m_context{ctx}
77 , m_endpoint{boost::asio::ip::make_address(conf.host), conf.port}
78 , m_socket{boost::asio::make_strand(ctx)}
79 {
80 }
81
82 void connect()
83 {
84 m_socket.connect(m_endpoint);
85 on_open();
86 }
87
88 bool connected() const { return m_connected; }
89
90 void close()
91 {
92 boost::asio::post(m_context, [this] {
93 m_socket.close();
94 on_close();
95 });
96 }
97
98 void write(const char* data, std::size_t sz)
99 {
100 boost::asio::write(m_socket, boost::asio::buffer(data, sz));
101 }
102
103 Nano::Signal<void()> on_open;
104 Nano::Signal<void()> on_close;
105 Nano::Signal<void()> on_fail;
106
107 boost::asio::io_context& m_context;
108 proto::endpoint m_endpoint;
109 proto::socket m_socket;
110 bool m_connected{false};
111};
112}