I try to implement a version of websocketpp server inside a mono-thread project that uses multiple coroutines based on boost fibers. The server is working fine but I'm having issue with the fact that the boost::fiber::sleep_for and other function does not yield back to the websocket.
Here is an example of my code:
#include "websocketpp/config/asio_no_tls.hpp"
#include "websocketpp/connection.hpp"
#include "websocketpp/server.hpp"
class Server {
private:
using WebsocketConn = std::shared_ptr<websocketpp::connection<websocketpp::config::asio>>;
websocketpp::server<websocketpp::config::asio> websocketServer;
std::function<void(WebsocketConn)> connectCallback;
std::function<void(WebsocketConn)> disconnectCallback;
public:
Server() {
websocketServer.set_reuse_addr(true);
websocketServer.set_error_channels(websocketpp::log::elevel::none);
websocketServer.set_access_channels(websocketpp::log::alevel::none);
websocketServer.init_asio();
websocketServer.set_open_handler(std::bind(&Server::onWebsocketOpen, this, std::placeholders::_1));
}
void listen(int port) {
websocketServer.listen(port);
websocketServer.start_accept();
websocketServer.run();// <= here is the blocking point based on the io_service used
}
void Server::onConnect(std::function<void(WebsocketConn)> callback) {
connectionCallback = callback;
}
void Server::onWebsocketOpen(websocketpp::connection_hdl connectionHandler) {
auto websocketConnection = websocketServer.get_con_from_hdl(connectionHandler);
connectionCallback(websocketConnection);
}
};
int main() {
Server server;
server.onConnect([](std::shared_ptr<websocketpp::connection<websocketpp::config::asio>> connection) {
boost::fibers::fiber([&](){
while (true) {
connection->send(/*some stuff*/); //This will never be sent until the loop is exited. After that it will send everything in one time.
boost::this_fiber::sleep_for(1000);
}
});
});
server.listen(8080);
}
if instead of fibers I use a thread it's working fine. Do you have any idea how to use fibers with websocketpp ? I know the init_asio function can take a pointer to an external io_service (which is responsible of the run function) but I tried using boost io_service and it's still the same behavior.
Thanks for the help