OSSIA
Open Scenario System for Interactive Application
Loading...
Searching...
No Matches
socketio_server.hpp
1#pragma once
2
3#include <ossia/network/context.hpp>
4#include <ossia/network/sockets/websocket_server_interface.hpp>
5#include <ossia/protocols/socketio/socketio_session.hpp>
6
7#include <boost/asio/ip/tcp.hpp>
8#include <boost/asio/steady_timer.hpp>
9#include <boost/asio/strand.hpp>
10#include <boost/beast/core.hpp>
11#include <boost/beast/http.hpp>
12#include <boost/beast/websocket.hpp>
13
14#include <memory>
15#include <mutex>
16#include <set>
17#include <string>
18
19namespace ossia::net
20{
21
22class socketio_server;
23
28 : public std::enable_shared_from_this<socketio_server_connection>
29{
30 friend class socketio_server;
31
32public:
34 boost::asio::ip::tcp::socket&& socket, socketio_server& server);
36
37 void run();
38 void send_text(const std::string& msg);
39 void send_text(const char* data, std::size_t sz);
40 void send_binary(std::string_view msg);
41 void close();
42
43 boost::asio::ip::tcp::socket& tcp_socket();
44 const std::string& sid() const { return m_config.sid; }
45
46private:
47 void do_read_http();
48 void on_read_http(boost::beast::error_code ec, std::size_t bytes);
49
50 // HTTP polling handlers
51 void handle_polling_get(
52 boost::beast::http::request<boost::beast::http::string_body>& req);
53 void handle_polling_post(
54 boost::beast::http::request<boost::beast::http::string_body>& req);
55 void handle_new_connection(
56 boost::beast::http::request<boost::beast::http::string_body>& req);
57 void send_http_response(
58 unsigned version, boost::beast::http::status status,
59 const std::string& body, const std::string& content_type = "text/plain");
60
61 // WebSocket mode
62 void do_accept_ws(
63 boost::beast::http::request<boost::beast::http::string_body> req);
64 void on_accept_ws(boost::beast::error_code ec);
65 void do_read_ws();
66 void on_read_ws(boost::beast::error_code ec, std::size_t bytes);
67
68 // Ping timer
69 void start_ping_timer();
70 void on_ping_timer(boost::beast::error_code ec);
71
72 // Engine.IO / Socket.IO processing
73 void process_engineio_message(std::string_view data);
74 void dispatch_socketio_message(std::string_view data);
75
76 static std::string generate_sid();
77
78 boost::beast::websocket::stream<boost::beast::tcp_stream> m_ws;
79 boost::beast::flat_buffer m_buffer;
80 boost::beast::http::request<boost::beast::http::string_body> m_http_req;
81 boost::asio::steady_timer m_ping_timer;
82 socketio_server& m_server;
83 engineio_config m_config;
84
85 // Buffered messages for long-polling GET
86 std::vector<std::string> m_poll_buffer;
87
88 bool m_is_websocket{false};
89 bool m_handshake_done{false};
90 bool m_upgraded{false};
91};
92
97class OSSIA_EXPORT socketio_server final : public websocket_server_interface
98{
99 friend class socketio_server_connection;
100
101public:
102 explicit socketio_server(ossia::net::network_context_ptr ctx);
103 ~socketio_server() override;
104
105 void listen(uint16_t port) override;
106 void run() override;
107 void stop() override;
108 void close(ws_connection_handle hdl) override;
109
110 void set_open_handler(ws_open_handler h) override;
111 void set_close_handler(ws_close_handler h) override;
112 void set_message_handler(ws_server_message_handler h) override;
113
114 std::string get_remote_ip(const ws_connection_handle& hdl) override;
115 std::string get_remote_endpoint(const ws_connection_handle& hdl) override;
116 std::string get_local_ip(const ws_connection_handle& hdl) override;
117
118 void send_message(ws_connection_handle hdl, const std::string& message) override;
119 void send_message(ws_connection_handle hdl, const server_reply& message) override;
120 void
121 send_message(ws_connection_handle hdl, const rapidjson::StringBuffer& message) override;
122 void send_binary_message(ws_connection_handle hdl, std::string_view message) override;
123
124private:
125 void do_accept();
126 void on_accept(boost::beast::error_code ec, boost::asio::ip::tcp::socket socket);
127 void add_connection(std::shared_ptr<socketio_server_connection> conn);
128 void remove_connection(std::shared_ptr<socketio_server_connection> conn);
129 socketio_server_connection* find_connection(const ws_connection_handle& hdl);
130
132 void send_sio_text(socketio_server_connection* conn, const std::string& msg);
134 void send_sio_binary(socketio_server_connection* conn, std::string_view msg);
135
136 ossia::net::network_context_ptr m_context;
137 boost::asio::ip::tcp::acceptor m_acceptor;
138 std::set<std::shared_ptr<socketio_server_connection>> m_connections;
139 std::mutex m_connections_mutex;
140
141 ws_open_handler m_on_open;
142 ws_close_handler m_on_close;
143 ws_server_message_handler m_on_message;
144};
145
146}
Definition socketio_server.hpp:29
Definition socketio_server.hpp:98
Definition websocket_server_interface.hpp:39
The message struct.
Definition message.hpp:29
Engine.IO configuration received from the server handshake.
Definition socketio_session.hpp:54