Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions cmake/OssiaDeps.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ if(Git_FOUND AND OSSIA_SUBMODULE_AUTOUPDATE)
tuplet
unordered_dense
verdigris
websocketpp
whereami
../cmake/cmake-modules
ios-cmake
Expand Down Expand Up @@ -107,7 +106,6 @@ include(deps/spdlog)
include(deps/tuplet)
include(deps/unordered_dense)
include(deps/verdigris)
include(deps/websocketpp)

if(OSSIA_PROTOCOL_COAP)
include(deps/coap)
Expand Down
11 changes: 11 additions & 0 deletions cmake/deps/abseil.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,17 @@ endif()
# add_subdirectory-based dependencies (rubberband, libremidi, ...).
if(NOT TARGET absl::strings)
block()
# A parent project (e.g. score) may have CMAKE_INCLUDE_CURRENT_DIR ON.
# That would add each Abseil target's own source/binary dir to its include
# path, and `absl/time/time.h` would then shadow the system <time.h>,
# breaking libstdc++'s <ctime>/<chrono>. Keep it off for Abseil's build.
# (Scoped to this block(), so the parent setting is untouched afterwards.)
set(CMAKE_INCLUDE_CURRENT_DIR OFF)
# A parent project (e.g. score) may build with CMAKE_UNITY_BUILD ON. Abseil's
# cctz sources are not unity-safe: time_zone_posix.cc and time_zone_fixed.cc
# each define a namespace-scope `kDigits`, so a merged TU fails with a
# redefinition. Build Abseil one TU at a time. (Scoped to this block().)
set(CMAKE_UNITY_BUILD OFF)
set(BUILD_SHARED_LIBS 0)
set(BUILD_TESTING 0)
set(ABSL_BUILD_TESTING OFF CACHE INTERNAL "")
Expand Down
91 changes: 44 additions & 47 deletions examples/Web/DoubleWSServer.cpp
Original file line number Diff line number Diff line change
@@ -1,53 +1,53 @@
#include <ossia/detail/config.hpp>

#include <ossia/detail/base64.hpp>
#include <ossia/network/base/parameter_data.hpp>
#include <ossia/network/context.hpp>
#include <ossia/network/generic/generic_device.hpp>
#include <ossia/network/local/local.hpp>
#include <ossia/network/oscquery/oscquery_server.hpp>
#include <ossia/network/sockets/websocket_server_beast.hpp>

#include <opencv2/imgcodecs.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/videoio.hpp>
#include <spdlog/sinks/stdout_sinks.h>
#include <websocketpp/base64/base64.hpp>
#include <websocketpp/config/asio_no_tls.hpp>
#include <websocketpp/server.hpp>

#include <boost/asio/post.hpp>

#include <atomic>
#include <chrono>
#include <iostream>
#include <set>
#include <thread>

// double websocket server test
// this example create a simple oscquery server that exposes its parameter through port 5678
// you can get the namespace in a browser with : ws://127.0.0.1:5678
// and it also creates a second web socket server to stream a webcam in JPEG on port 9003
// to see it, open the file double_ws_server-test.html (next to this one) in a browser
// KNOWN issue : as soon as you start the second ws server, the first one doesn't respond anymore

typedef websocketpp::server<websocketpp::config::asio> server;

using websocketpp::connection_hdl;
using websocketpp::lib::bind;
using websocketpp::lib::placeholders::_1;
using websocketpp::lib::placeholders::_2;

using namespace std;
using namespace ossia;

class broadcast_server
{
public:
broadcast_server()
explicit broadcast_server(ossia::net::network_context_ptr ctx)
: m_ctx{std::move(ctx)}
, m_server{m_ctx}
{
m_server.init_asio();

m_server.set_open_handler(bind(&broadcast_server::on_open, this, ::_1));
m_server.set_close_handler(bind(&broadcast_server::on_close, this, ::_1));
m_server.set_message_handler(bind(&broadcast_server::on_message, this, ::_1, ::_2));

m_server.clear_access_channels(
websocketpp::log::alevel::frame_header
| websocketpp::log::alevel::frame_payload);
using namespace ossia::net;
m_server.set_open_handler(
[this](ws_connection_handle hdl) { m_connections.insert(hdl); });
m_server.set_close_handler(
[this](ws_connection_handle hdl) { m_connections.erase(hdl); });
m_server.set_message_handler(
[](const ws_connection_handle&, ws_opcode, const std::string&) {
return server_reply{};
});

m_cap_thread = std::thread([&]() {
m_cap_thread = std::thread([this]() {
std::vector<int> compression_params;
compression_params.push_back(cv::IMWRITE_JPEG_QUALITY);
compression_params.push_back(20);
Expand All @@ -68,45 +68,45 @@ class broadcast_server
if(cv::imencode(".jpg", small, jpeg_buf, compression_params))
{
std::string encoded
= websocketpp::base64_encode(jpeg_buf.data(), jpeg_buf.size());

con_list::iterator it;
for(it = m_connections.begin(); it != m_connections.end(); ++it)
{
m_server.send(*it, encoded, websocketpp::frame::opcode::text);
}
= ossia::base64_encode(jpeg_buf.data(), jpeg_buf.size());

// The connection list and the actual writes are handled on the
// server's io_context thread so we don't race with the strand
// that runs accept / read / close handlers.
boost::asio::post(m_ctx->context, [this, msg = std::move(encoded)] {
for(auto& hdl : m_connections)
m_server.send_message(hdl, msg);
});
}
usleep(30000);
std::this_thread::sleep_for(std::chrono::milliseconds(30));
}
}
});
}

void on_open(connection_hdl hdl) { m_connections.insert(hdl); }

void on_close(connection_hdl hdl) { m_connections.erase(hdl); }

void on_message(connection_hdl hdl, server::message_ptr msg)
~broadcast_server()
{
//for (auto it : m_connections) {
// m_server.send(it,msg);
// }
m_quit = true;
if(m_cap_thread.joinable())
m_cap_thread.join();
}

void run(uint16_t port)
{
m_server.listen(port);
m_server.start_accept();
m_server.run();
}

private:
typedef std::set<connection_hdl, std::owner_less<connection_hdl>> con_list;
using con_list = std::set<
ossia::net::ws_connection_handle,
std::owner_less<ossia::net::ws_connection_handle>>;

server m_server;
ossia::net::network_context_ptr m_ctx;
ossia::net::websocket_server_beast m_server;
con_list m_connections;

bool m_quit = false;
std::atomic_bool m_quit{false};
std::thread m_cap_thread;
};

Expand Down Expand Up @@ -151,10 +151,7 @@ int main()
});
push_thread.detach();

broadcast_server server;
// comment the following to make ossia ws server work again
auto ctx = std::make_shared<ossia::net::network_context>();
broadcast_server server{ctx};
server.run(9003);

while(true)
;
}
4 changes: 2 additions & 2 deletions examples/Web/JpegStreamer.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#include <ossia/detail/base64.hpp>
#include <ossia/network/generic/generic_device.hpp>
#include <ossia/network/oscquery/oscquery_server.hpp>

#include <opencv2/imgcodecs.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/videoio.hpp>
#include <websocketpp/base64/base64.hpp>

int main(int, char**)
{
Expand Down Expand Up @@ -37,7 +37,7 @@ int main(int, char**)
if(cv::imencode(".jpg", small, jpeg_buf, compression_params))
{
std::string encoded
= websocketpp::base64_encode(jpeg_buf.data(), jpeg_buf.size());
= ossia::base64_encode(jpeg_buf.data(), jpeg_buf.size());
param->push_value(encoded);
}
using namespace std::chrono_literals;
Expand Down
1 change: 0 additions & 1 deletion src/ossia-max/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@ ossia_set_visibility(${PROJECT_NAME})
target_link_libraries(${PROJECT_NAME} PRIVATE ossia
$<LINK_ONLY:$<$<BOOL:${WIN32}>:${MAXSDK_API_LIBRARY}>>
$<LINK_ONLY:re2::re2>
$<LINK_ONLY:websocketpp::websocketpp>
)

generate_export_header(${PROJECT_NAME})
Expand Down
40 changes: 15 additions & 25 deletions src/ossia-qt/protocols/qml_ws_outbound_socket.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#pragma once
#include <ossia/network/context.hpp>
#include <ossia/network/sockets/udp_socket.hpp>
#include <ossia/network/sockets/websocket_client.hpp>
#include <ossia/network/sockets/websocket_client_beast.hpp>
#include <ossia/network/sockets/websocket_common.hpp>

#include <ossia-qt/protocols/utils.hpp>

Expand All @@ -25,7 +26,7 @@ class qml_websocket_outbound_socket
struct state
{
std::string url;
std::unique_ptr<ossia::net::websocket_client> client;
std::unique_ptr<ossia::net::websocket_client_beast> client;
std::atomic_bool alive{true};
};

Expand All @@ -50,13 +51,14 @@ class qml_websocket_outbound_socket
m_state->url = "ws://" + conf.host + ":" + std::to_string(conf.port); // FIXME wss
auto st = m_state;
auto self = QPointer{this};
m_state->client = std::make_unique<ossia::net::websocket_client>(
ctx, [st, self](auto hdl, auto opcode, const std::string& msg) {
m_state->client = std::make_unique<ossia::net::websocket_client_beast>(
ctx, ossia::net::ws_client_message_handler{
[st, self](const ossia::net::ws_connection_handle&, ossia::net::ws_opcode opcode, std::string& msg) {
if(!st->alive)
return;
if(auto* ptr = self.get())
ptr->on_message(hdl, opcode, msg);
});
ptr->on_message(opcode, msg);
}});

if(onOpen.isCallable())
m_state->client->on_open.connect<&qml_websocket_outbound_socket::on_open>(this);
Expand All @@ -68,13 +70,13 @@ class qml_websocket_outbound_socket
m_state->client->connect(m_state->url);
}

void on_message(auto hdl, auto opcode, const std::string& msg)
void on_message(ossia::net::ws_opcode opcode, const std::string& msg)
{
if(opcode == websocketpp::frame::opcode::text && onTextMessage.isCallable())
if(opcode == ossia::net::ws_opcode::text && onTextMessage.isCallable())
{
onTextMessage.call({QString::fromStdString(msg)});
}
else if(opcode == websocketpp::frame::opcode::binary && onBinaryMessage.isCallable())
else if(opcode == ossia::net::ws_opcode::binary && onBinaryMessage.isCallable())
{
onBinaryMessage.call(
{qjsEngine(this)->toScriptValue(QByteArray(msg.data(), msg.size()))});
Expand Down Expand Up @@ -107,12 +109,8 @@ class qml_websocket_outbound_socket
if(!m_state)
return;
auto st = m_state;
boost::asio::dispatch(
st->client->context(),
[st, msg = message.toStdString()] {
if(st->alive)
st->client->send_message(msg);
});
if(st->alive)
st->client->send_message(message.toStdString());
}
W_SLOT(write)

Expand All @@ -121,12 +119,8 @@ class qml_websocket_outbound_socket
if(!m_state)
return;
auto st = m_state;
boost::asio::dispatch(
st->client->context(),
[st, buf = std::string(buffer.data(), buffer.size())] {
if(st->alive)
st->client->send_binary_message(buf);
});
if(st->alive)
st->client->send_binary_message(std::string_view(buffer.data(), buffer.size()));
}
W_SLOT(writeBinary)

Expand All @@ -140,10 +134,6 @@ class qml_websocket_outbound_socket
}
W_SLOT(close)

// FIXME
// void osc(QByteArray address, QJSValueList values) { this->send_osc(address, values); }
// W_SLOT(osc)

QJSValue onOpen;
QJSValue onClose;
QJSValue onError;
Expand Down
Loading
Loading