OSSIA
Open Scenario System for Interactive Application
Loading...
Searching...
No Matches
oscquery_server_asio.hpp
1#pragma once
2#include <ossia/detail/hash_map.hpp>
3#include <ossia/detail/lockfree_queue.hpp>
4#include <ossia/detail/mutex.hpp>
5#include <ossia/network/base/listening.hpp>
6#include <ossia/network/base/protocol.hpp>
7#include <ossia/network/context_functions.hpp>
8#include <ossia/network/generic/generic_device.hpp>
9#include <ossia/network/sockets/websocket_common.hpp>
10#include <ossia/network/sockets/websocket_reply.hpp>
11#include <ossia/network/zeroconf/zeroconf.hpp>
12#include <ossia/protocols/osc/osc_factory.hpp>
13
14#include <nano_signal_slot.hpp>
15
16#include <atomic>
17namespace osc
18{
19template <typename T>
20class sender;
21class receiver;
22}
23namespace oscpack
24{
25class ReceivedMessage;
26class IpEndpointName;
27}
28namespace ossia
29{
30namespace net
31{
32class websocket_server_interface;
33}
34namespace oscquery
35{
36class query_answerer;
37class get_query_answerer;
38struct json_query_answerer;
39}
40namespace oscquery_asio
41{
42struct oscquery_client;
43using clients = std::vector<std::unique_ptr<oscquery_client>>;
46{
47 friend struct oscquery_client;
48 friend class ossia::oscquery::query_answerer;
51
52public:
53 using connection_handler = std::weak_ptr<void>;
54
55 // Use oscquery_server_protocol_with_osc
57 ossia::net::network_context_ptr ctx, uint16_t, uint16_t)
58 = delete;
59
61 ossia::net::network_context_ptr ctx,
62 const std::vector<ossia::net::osc_server_configuration>& conf, uint16_t ws_port,
63 bool forceWS);
65
66 bool pull(net::parameter_base&) override;
67 std::future<void> pull_async(net::parameter_base&) override;
68 void request(net::parameter_base&) override;
69 bool push(const net::parameter_base&, const ossia::value& v) override;
70 bool push_raw(const ossia::net::full_parameter_data& parameter_base) override;
71 bool push_bundle(const std::vector<const ossia::net::parameter_base*>&) override;
72 bool push_raw_bundle(const std::vector<ossia::net::full_parameter_data>&) override;
73 bool echo_incoming_message(
74 const ossia::net::message_origin_identifier&, const ossia::net::parameter_base&,
75 const ossia::value& v) override;
76 bool observe(net::parameter_base&, bool) override;
77 bool observe_quietly(net::parameter_base&, bool) override;
78 bool update(net::node_base& b) override;
79
80 void set_device(net::device_base& dev) override;
81 void stop() override;
82 ossia::net::device_base& get_device() const noexcept { return *m_device; }
83
84 int get_ws_port() const noexcept { return m_wsPort; }
85
86 bool force_ws() const noexcept { return m_forceWS.load(std::memory_order_relaxed); }
87 void set_force_ws(bool forceWS) noexcept;
88
89 const std::vector<ossia::net::osc_server_configuration>&
90 get_transports() const noexcept
91 {
92 return m_oscConf;
93 }
94
95 Nano::Signal<void(const std::string&)> onClientConnected;
96 Nano::Signal<void(const std::string&)> onClientDisconnected;
97
98protected:
99 explicit oscquery_server_protocol_base(ossia::net::network_context_ptr ctx) = delete;
100
101 // OSC callback
102 void on_osc_message(const oscpack::ReceivedMessage& m);
103 void process_raw_osc_data(const char* data, std::size_t sz);
104
105 // List of connected clients
106 oscquery_client* find_client(const connection_handler& hdl);
107
108 void add_node(std::string_view path, const string_map<std::string>& parameters);
109 void remove_node(std::string_view path, const std::string& node);
110 void rename_node(std::string_view node, const std::string& new_name);
111
112 // Websocket callbacks
113 void on_connectionOpen(const connection_handler& hdl);
114 void on_connectionClosed(const connection_handler& hdl);
115
116 // Local device callback
117 void on_nodeCreated(const ossia::net::node_base&);
118 void on_nodeRemoved(const ossia::net::node_base&);
119 void on_parameterChanged(const ossia::net::parameter_base&);
120 void on_attributeChanged(const ossia::net::node_base&, std::string_view attr);
121 void on_nodeRenamed(const ossia::net::node_base& n, std::string oldname);
122
123 template <typename T>
124 bool push_impl(const T& addr, const ossia::value& v);
125
126 bool write_impl(std::string_view data, bool critical);
127
128 void update_zeroconf();
129 // Exceptions here will be catched by the server
130 // which will set appropriate error codes.
131 ossia::net::server_reply
132 on_text_ws_message(const connection_handler& hdl, const std::string& message);
133 ossia::net::server_reply
134 on_binary_ws_message(const connection_handler& hdl, const std::string& message);
135
136 ossia::net::network_context_ptr m_context;
137
138 std::unique_ptr<ossia::net::websocket_server_interface> m_websocketServer;
139
140 net::zeroconf_server m_zeroconfServerWS;
141
142 // What we expose over OSC
143 std::vector<ossia::net::osc_server_configuration> m_oscConf;
144
145 // Listening status of the local software
146 net::listened_parameters m_listening;
147
148 // The clients connected to this server
149 clients m_clients;
150 std::atomic_int m_clientCount{};
151
152 ossia::net::device_base* m_device{};
153
154 // To lock m_clients
155 mutex_t m_clientsMutex;
156
157 // The local ports
158 uint16_t m_wsPort{};
159
160 // Will only send changes through WS
161 std::atomic_bool m_forceWS{};
162};
163
164class OSSIA_EXPORT oscquery_server_protocol : public oscquery_server_protocol_base
165{
166public:
167 struct osc_receiver_impl;
168 explicit oscquery_server_protocol(
169 ossia::net::network_context_ptr ctx, uint16_t osc_port = 1234,
170 uint16_t ws_port = 5678, bool forceWS = false);
171 ~oscquery_server_protocol();
172
173 void update_zeroconf();
174 void set_device(net::device_base& dev) override;
175 void stop() override;
176 int get_osc_port() const noexcept { return m_oscPort; }
177
178private:
179 uint16_t m_oscPort{};
180 std::unique_ptr<osc_receiver_impl> m_oscServer;
181
182 net::zeroconf_server m_zeroconfServerOSC;
183};
184}
185}
Root of a device tree.
Definition ossia/network/base/device.hpp:58
The node_base class.
Definition node.hpp:48
The parameter_base class.
Definition ossia/network/base/parameter.hpp:48
The protocol_base class.
Definition protocol.hpp:40
OSCQuery get query-answering logic.
Definition get_query_parser.hpp:26
Implementation of an oscquery server.
Definition oscquery_server_asio.hpp:46
The value class.
Definition value.hpp:173
Definition git_info.h:7
The message struct.
Definition message.hpp:29
Full information about a parameter.
Definition parameter_data.hpp:61
OSCQuery JSON query-answering logic.
Definition json_query_parser.hpp:16