Currently i am writing a C++ Websocket Client Library which get wrapped in a C# Library.
I am using Boost Beast for the websocket connection.
Now i am at the point that i start a async_read when the handshake is completed so the websocket dont disconnect.
The Problem is the io_content blocks the thread so the C# program stops excecuting until the async_read gets a timeout and the io_content returns. But i want that the C# program keep executing.
I tried to execute the connect function in a thread, but there's the problem, that the next function that the C# program calls is a write operation and it crashes, because the connect function is still connecting...
library.cpp:
void OpenConnection(char* id)
{
std::cout << "Opening new connection..." << std::endl;
std::shared_ptr<Session> session = std::make_shared<Session>();
session->connect();
sessions.emplace(std::string(id), std::move(session));
}
session.cpp:
void Session::connect()
{
resolver.async_resolve(
"websocket_uri",
"443",
beast::bind_front_handler(
&Session::on_resolve,
shared_from_this()));
ioc.run();
}
The on_resolve,on_connect,on_handshake... are the same as here: https://www.boost.org/doc/libs/1_70_0/libs/beast/example/websocket/client/async-ssl/websocket_client_async_ssl.cpp
Unless the on_handshake function:
void Session::on_handshake(beast::error_code ec)
{
if (ec)
return fail(ec, "handshake");
ws.async_read(buffer, beast::bind_front_handler(&Session::on_read, shared_from_this()));
}
And the on_read function:
void Session::on_read(beast::error_code ec, std::size_t bytes_transfered)
{
boost::ignore_unused(bytes_transfered);
if (ec)
return fail(ec, "read");
std::cout << "Got message" << std::endl;
onMessage(Message::parseMessage(beast::buffers_to_string(buffer.data())));
ws.async_read(buffer, beast::bind_front_handler(&Session::on_read, shared_from_this()));
}
And the on_write function:
void Session::on_write(beast::error_code ec, std::size_t bytes_transfered)
{
boost::ignore_unused(bytes_transfered);
if (ec)
return fail(ec, "write");
queue.erase(queue.begin());
if (!queue.empty())
{
ws.async_write(net::buffer(queue.front()->toString()), beast::bind_front_handler(&Session::on_write, shared_from_this()));
}
}
C# Program(For testing):
[DllImport(@"/data/cpp_projects/whatsapp_web_library/build/Debug/libWhatsApp_Web_Library.so")]
public static extern void OpenConnection(string id);
[DllImport(@"/data/cpp_projects/whatsapp_web_library/build/Debug/libWhatsApp_Web_Library.so")]
public static extern void CloseConnection(string id);
[DllImport(@"/data/cpp_projects/whatsapp_web_library/build/Debug/libWhatsApp_Web_Library.so")]
public static extern void GenerateQRCode(string id);
static void Main(string[] args)
{
string id = "test";
OpenConnection(id);
GenerateQRCode(id);
}
Now is my question, how can i implement this?
I have been stuck on this problem for 3 days now and am slowly despairing.
Thanks already :)