Skip to content

Commit

Permalink
Create watchdog upon connect instead of before (#272)
Browse files Browse the repository at this point in the history
  • Loading branch information
abhaybd authored and AyushKulk committed Oct 31, 2023
1 parent c00a06d commit a00ed3f
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 23 deletions.
48 changes: 25 additions & 23 deletions src/network/websocket/WebSocketServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,27 +83,6 @@ bool SingleClientWSServer::addProtocol(std::unique_ptr<WebSocketProtocol> protoc
std::string path = protocol->getProtocolPath();
if (protocolMap.find(path) == protocolMap.end()) {
protocolMap.emplace(path, std::move(protocol));
auto& protocolData = protocolMap.at(path);
const auto& heartbeatInfo = protocolData.protocol->heartbeatInfo;
if (heartbeatInfo.has_value()) {
auto eventID =
pingScheduler.scheduleEvent(heartbeatInfo->first / 2, [this, path]() {
auto& pd = this->protocolMap.at(path);
std::lock_guard lock(pd.mutex);
if (pd.client.has_value()) {
log(LOG_DEBUG, "Ping!\n");
server.ping(pd.client.value(), path);
}
});
std::lock_guard l(protocolData.mutex);
// util::Watchdog is non-copyable and non-movable, so we must create in-place
// Since we want to create a member field of the pair in-place, it gets complicated
// so we have to use piecewise_construct to allow us to separately initialize all
// pair fields in-place
protocolData.heartbeatInfo.emplace(std::piecewise_construct,
std::tuple<decltype(eventID)>{eventID},
util::pairToTuple(heartbeatInfo.value()));
}
return true;
} else {
return false;
Expand Down Expand Up @@ -159,8 +138,31 @@ void SingleClientWSServer::onOpen(connection_hdl hdl) {
path.c_str(), client.c_str());

auto& protocolData = protocolMap.at(path);
protocolData.client = hdl;
protocolData.protocol->clientConnected();
{
std::lock_guard lock(protocolData.mutex);
protocolData.client = hdl;
const auto& heartbeatInfo = protocolData.protocol->heartbeatInfo;
if (heartbeatInfo.has_value()) {
auto eventID =
pingScheduler.scheduleEvent(heartbeatInfo->first / 2, [this, path]() {
auto& pd = this->protocolMap.at(path);
std::lock_guard lock(pd.mutex);
if (pd.client.has_value()) {
log(LOG_DEBUG, "Ping!\n");
server.ping(pd.client.value(), path);
}
});
// util::Watchdog is non-copyable and non-movable, so we must create in-place
// Since we want to create a member field of the pair in-place, it gets complicated
// so we have to use piecewise_construct to allow us to separately initialize all
// pair fields in-place
protocolData.heartbeatInfo.emplace(std::piecewise_construct,
std::tuple<decltype(eventID)>{eventID},
util::pairToTuple(heartbeatInfo.value()));
}

protocolData.protocol->clientConnected();
}
}

void SingleClientWSServer::onClose(connection_hdl hdl) {
Expand Down
7 changes: 7 additions & 0 deletions src/network/websocket/WebSocketServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ class SingleClientWSServer {
ProtocolData(std::unique_ptr<WebSocketProtocol> protocol);
const std::unique_ptr<WebSocketProtocol> protocol;
std::optional<connection_hdl> client;
// holds the periodically scheduled ping event and the watchdog
std::optional<std::pair<util::PeriodicScheduler<>::eventid_t, util::Watchdog<>>>
heartbeatInfo;
std::mutex mutex;
Expand All @@ -108,14 +109,20 @@ class SingleClientWSServer {
uint16_t port;
websocketpp::server<websocketpp::config::asio> server;
bool isRunning;
// maps path prefix to ProtocolData for each protocol
std::map<std::string, ProtocolData> protocolMap;
std::thread serverThread;
util::PeriodicScheduler<> pingScheduler;

// called when connection is received and being validated.
// return true to accept, false to reject
bool validate(connection_hdl hdl);
// called when connection is opened
void onOpen(connection_hdl hdl);
// called when connection is closed
void onClose(connection_hdl hdl);
void onMessage(connection_hdl hdl, message_t message);
// called when pong message received from WS client
void onPong(connection_hdl hdl, const std::string& payload);
void serverTask();
};
Expand Down

0 comments on commit a00ed3f

Please sign in to comment.