72struct websocket_log_sink final
73 :
public spdlog::sinks::sink
74 ,
public Nano::Observer
76 websocket_log_sink(std::shared_ptr<websocket_threaded_connection> s, std::string send)
77 : socket{std::move(s)}
78 , sender{std::move(send)}
80 socket->socket.on_open.connect<&websocket_log_sink::open_fun>(
this);
86 while(logs.try_dequeue(m))
88 socket->socket.send_message(m);
92 ~websocket_log_sink()
override
94 socket->socket.on_open.disconnect<&websocket_log_sink::open_fun>(
this);
97 void make_message(
const spdlog::details::log_msg& msg)
101 ossia::json_writer writer{buffer};
103 writer.StartObject();
105 writer.Key(
"operation");
106 writer.String(
"log");
111 case spdlog::level::trace:
112 writer.String(
"trace");
114 case spdlog::level::debug:
115 writer.String(
"debug");
117 case spdlog::level::info:
118 writer.String(
"info");
120 case spdlog::level::warn:
121 writer.String(
"warn");
123 case spdlog::level::err:
124 writer.String(
"error");
126 case spdlog::level::critical:
127 writer.String(
"critical");
129 case spdlog::level::off:
130 writer.String(
"off");
134 writer.Key(
"sender");
135 writer.String(sender.data(), sender.size());
137 writer.Key(
"message");
138 writer.String(msg.payload.data(), msg.payload.size());
143 void send_message(
const spdlog::details::log_msg& msg)
146 socket->socket.send_message(buffer);
149 void log(
const spdlog::details::log_msg& msg)
override
151 if(!socket->socket.connected())
154 logs.enqueue(std::string{buffer.GetString(), buffer.GetSize()});
163 void flush()
override { }
165 void set_pattern(
const std::string& pattern)
override { }
166 void set_formatter(std::unique_ptr<spdlog::formatter> sink_formatter)
override { }
169 rapidjson::StringBuffer buffer;
170 std::shared_ptr<websocket_threaded_connection> socket;
173 moodycamel::ReaderWriterQueue<std::string> logs;
177struct websocket_heartbeat :
public Nano::Observer
181 std::shared_ptr<websocket_threaded_connection> t, std::string s,
182 std::chrono::seconds dur)
190 if(init && conn->socket.connected())
193 ossia::json_writer writer{buffer};
194 writer.StartObject();
196 writer.Key(
"operation");
197 writer.String(
"alive");
199 writer.Key(
"sender");
200 writer.String(sender.data(), sender.size());
204 conn->socket.send_message(buffer);
207 for(
int i = 0; i < 100; i++)
209 std::this_thread::sleep_for(
210 std::chrono::duration_cast<std::chrono::milliseconds>(interval) / 100.0);
217 t->socket.on_open.connect<&websocket_heartbeat::open_fun>(*this);
222 conn->socket.send_message(init_msg);
226 ~websocket_heartbeat()
228 conn->socket.on_open.disconnect<&websocket_heartbeat::open_fun>(*this);
230 if(thread.joinable())
235 send_init(
const ossia::hash_map<std::string, ossia::variant<std::string, int>>& map)
237 rapidjson::StringBuffer buffer;
238 ossia::json_writer writer{buffer};
239 writer.StartObject();
241 writer.Key(
"operation");
242 writer.String(
"initWatchdog");
244 writer.Key(
"sender");
245 writer.String(sender.data(), sender.size());
247 writer.Key(
"aliveTime");
248 writer.Int(interval.count());
252 ossia::json_writer& writer;
253 void operator()(
const std::string& s) { writer.String(s); }
255 void operator()(
int s) { writer.Int(s); }
258 for(
const auto&
pair : map)
260 writer.Key(
pair.first);
261 ossia::visit(sw,
pair.second);
266 if(conn->socket.connected())
268 conn->socket.send_message(buffer);
273 init_msg = std::string(buffer.GetString(), buffer.GetSize());
278 rapidjson::StringBuffer buffer;
280 std::chrono::seconds interval;
282 std::string init_msg;
283 std::shared_ptr<websocket_threaded_connection> conn;
284 std::atomic_bool running{
true};
285 std::atomic_bool init{
false};