Cadabra
Computer algebra system for field theory problems
Loading...
Searching...
No Matches
websocket_server.hh
Go to the documentation of this file.
1#pragma once
2
3#include <boost/beast/core.hpp>
4#include <boost/beast/websocket.hpp>
5#include <boost/beast/http.hpp>
6#include <boost/asio/ip/tcp.hpp>
7#include <functional>
8#include <memory>
9#include <string>
10#include <queue>
11#include <optional>
12#include <unordered_map>
13#include <iostream>
14#include <pthread.h>
15
17 public:
18 using id_type = std::size_t;
19 using request_type = boost::beast::http::request<boost::beast::http::string_body>;
20 using response_type = boost::beast::http::response<boost::beast::http::string_body>;
21
22 using message_handler = std::function<void(id_type, const std::string&, const request_type&, const std::string& ip_address)>;
23 using connect_handler = std::function<void(id_type)>;
24 using disconnect_handler = std::function<void(id_type)>;
25 using http_handler = std::function<void(request_type&, response_type&)>;
26
27 websocket_server() = default;
28 explicit websocket_server(uint16_t port);
30
33
34 // Change the port on which to listen.
35 void listen(uint16_t port);
36
41
42 // You should call `run` on a separate thread to start the
43 // listening process. All callbacks on the message handlers will
44 // come on this thread. It is safe to call `send` below from a
45 // different thread.
46 void run();
47 void stop();
48
49 // Send a message. This is safe on a thread which is not the
50 // thread which called `run`.
51 void send(id_type id, const std::string& message);
52 void close(id_type id);
53
54 uint16_t get_local_port() const;
55
56 private:
57 // The connection class handles all actual communication. There
58 // is one instance for each connection. Connections are
59 // identified by the single `id_type` stored as `id`.
60
61 class connection : public std::enable_shared_from_this<connection> {
62 public:
63 connection(boost::asio::io_context& ioc, websocket_server& server, id_type id);
64
65 void start();
66 void send(const std::string& message);
67 void close();
68
70
71 private:
72 void on_read_request(boost::beast::error_code ec, std::size_t);
73 void on_websocket_accept(boost::beast::error_code ec);
74 void do_read_websocket();
75 void on_read_websocket(boost::beast::error_code ec, std::size_t);
76 void do_write();
77 void on_write(boost::beast::error_code ec, std::size_t);
78 void on_close(boost::beast::error_code ec);
80
81 boost::asio::ip::tcp::socket socket_;
82 std::optional<boost::beast::websocket::stream<boost::asio::ip::tcp::socket&>> ws_stream_;
83 boost::beast::flat_buffer buffer_;
86
89 public:
91 // std::cerr << "Thread " << pthread_self() << " queued_message constructor " << (void*)this << std::endl;
92 }
94 // std::cerr << "Thread " << pthread_self() << " queued_message destructor " << (void*)this << std::endl;
95 }
96
97 std::string data;
98 std::shared_ptr<boost::beast::flat_buffer> buffer;
99 int seq;
100 };
101 bool is_websocket_{false};
102
103 std::mutex queue_mutex_; // lock this for access to the variables below
104 std::queue<queued_message> message_queue_;
105 bool writing_{false};
106 };
107
108 void do_accept();
109 void remove_connection(id_type id);
110
111 boost::asio::io_context ioc_;
112 std::optional<boost::asio::ip::tcp::acceptor> acceptor_;
113 std::unordered_map<id_type, std::shared_ptr<connection>> connections_;
115
120};
121
Definition websocket_server.hh:88
~queued_message()
Definition websocket_server.hh:93
queued_message()
Definition websocket_server.hh:90
int seq
Definition websocket_server.hh:99
std::string data
Definition websocket_server.hh:97
std::shared_ptr< boost::beast::flat_buffer > buffer
Definition websocket_server.hh:98
Definition websocket_server.hh:61
void on_websocket_accept(boost::beast::error_code ec)
Definition websocket_server.cc:81
void close()
Definition websocket_server.cc:169
bool is_websocket_
Definition websocket_server.hh:101
void on_close(boost::beast::error_code ec)
Definition websocket_server.cc:200
boost::asio::ip::tcp::socket socket_
Definition websocket_server.hh:81
std::queue< queued_message > message_queue_
Definition websocket_server.hh:104
void do_write()
Definition websocket_server.cc:147
std::optional< boost::beast::websocket::stream< boost::asio::ip::tcp::socket & > > ws_stream_
Definition websocket_server.hh:82
id_type id_
Definition websocket_server.hh:87
void on_read_websocket(boost::beast::error_code ec, std::size_t)
Definition websocket_server.cc:105
bool writing_
Definition websocket_server.hh:105
void do_read_websocket()
Definition websocket_server.cc:95
void handle_http_request()
Definition websocket_server.cc:47
void start()
Definition websocket_server.cc:11
websocket_server & server_
Definition websocket_server.hh:85
void send(const std::string &message)
Definition websocket_server.cc:123
boost::beast::flat_buffer buffer_
Definition websocket_server.hh:83
websocket_server::request_type http_request_
Definition websocket_server.hh:84
void on_read_request(boost::beast::error_code ec, std::size_t)
Definition websocket_server.cc:24
void on_write(boost::beast::error_code ec, std::size_t)
Definition websocket_server.cc:184
std::mutex queue_mutex_
Definition websocket_server.hh:103
friend websocket_server
Definition websocket_server.hh:69
Definition websocket_server.hh:16
boost::asio::io_context ioc_
Definition websocket_server.hh:111
void close(id_type id)
Definition websocket_server.cc:283
uint16_t get_local_port() const
Definition websocket_server.cc:228
connect_handler connect_handler_
Definition websocket_server.hh:117
id_type next_connection_id_
Definition websocket_server.hh:114
void set_http_handler(http_handler h)
Definition websocket_server.cc:248
boost::beast::http::request< boost::beast::http::string_body > request_type
Definition websocket_server.hh:19
void stop()
Definition websocket_server.cc:309
std::function< void(id_type, const std::string &, const request_type &, const std::string &ip_address)> message_handler
Definition websocket_server.hh:22
void set_disconnect_handler(disconnect_handler h)
Definition websocket_server.cc:243
void send(id_type id, const std::string &message)
Definition websocket_server.cc:276
disconnect_handler disconnect_handler_
Definition websocket_server.hh:118
std::unordered_map< id_type, std::shared_ptr< connection > > connections_
Definition websocket_server.hh:113
std::function< void(id_type)> connect_handler
Definition websocket_server.hh:23
std::size_t id_type
Definition websocket_server.hh:18
boost::beast::http::response< boost::beast::http::string_body > response_type
Definition websocket_server.hh:20
void set_message_handler(message_handler h)
Definition websocket_server.cc:233
message_handler message_handler_
Definition websocket_server.hh:116
http_handler http_handler_
Definition websocket_server.hh:119
std::optional< boost::asio::ip::tcp::acceptor > acceptor_
Definition websocket_server.hh:112
websocket_server()=default
void listen(uint16_t port)
Definition websocket_server.cc:215
void remove_connection(id_type id)
Definition websocket_server.cc:290
~websocket_server()
Definition websocket_server.cc:210
std::function< void(request_type &, response_type &)> http_handler
Definition websocket_server.hh:25
websocket_server(const websocket_server &)=delete
void do_accept()
Definition websocket_server.cc:253
std::function< void(id_type)> disconnect_handler
Definition websocket_server.hh:24
void run()
Definition websocket_server.cc:298
websocket_server & operator=(const websocket_server &)=delete
void set_connect_handler(connect_handler h)
Definition websocket_server.cc:238