websocketpp
websocketpp copied to clipboard
messages sent in wrong order (race condition?)
Perhaps this is related to #149.
I'm also having an issue with out-of-order messages.
All my messages have a sequence number, and I detect out-of-order messages on the receiving side based on such sequence number.
But I call srv->send() always from the same thread, so I don't expect message order to be scrambled.
This only happens when I have a large message, and immediately after that, other messages are sent, and the large message ends up being received after those messages, e.g. like:
// following calls happen in a very short timeframe, i.e. in a burst:
srv->send(c, "731 - large message");
srv->send(c, "732 - small message 1");
srv->send(c, "733 - small message 2");
on the receiving end, I receive the message in this order: 732, 733, 731.
Conversely, if I "spread" the calls to srv->send() over time, messages arrive in the meant order.
So my first guess is that when I call srv->send(), and an hypothetical background thread (asio stuff?) is still somewhat working on that previous large message, messages queue up in an undetermined order, and are ultimately sent in the wrong order.
How can I make sure messages are sent in the order srv->send() is called?
Server setup:
#include <websocketpp/config/asio_no_tls.hpp>
#include <websocketpp/server.hpp>
#include <websocketpp/logger/basic.hpp>
#include <websocketpp/common/cpp11.hpp>
#include <websocketpp/logger/levels.hpp>
struct my_config : public websocketpp::config::asio
{
typedef websocketpp::log::my_logger<concurrency_type, websocketpp::log::elevel> elog_type;
typedef websocketpp::log::my_logger<concurrency_type, websocketpp::log::alevel> alog_type;
struct my_transport_config : public websocketpp::config::asio::transport_config
{
typedef my_config::alog_type alog_type;
typedef my_config::elog_type elog_type;
};
typedef websocketpp::transport::asio::endpoint<my_transport_config> transport_type;
};
typedef websocketpp::server<my_config> my_server;
typedef my_server::connection_type my_connection;
and initialisation:
my_server *srv = new my_server;
srv->set_user_agent(*sim::getStringNamedParam("simWS.userAgent"));
auto verbose = sim::getStringNamedParam("simWS.verbose");
srv->set_access_channels(websocketpp::log::alevel::none);
srv->init_asio();
// omissis: a few calls to srv->set_XXX_handler ....
srv->listen(1234);
srv->start_accept();
sending message to client:
auto c = shared_ptr<my_connection>(connPtr, [=](my_connection*){});
srv->send(c, data, opcode);