Experiment of notification via NotifyClient + JSON API

This commit is contained in:
Gioacchino Mazzurco 2018-06-29 16:03:09 +02:00
parent 130007b578
commit 1bc518041c
No known key found for this signature in database
GPG key ID: A1FBCA3872E87051
5 changed files with 142 additions and 50 deletions

View file

@ -18,19 +18,40 @@
#include "jsonapi.h"
#include <rapid_json/document.h>
#include <rapid_json/writer.h>
#include <rapid_json/stringbuffer.h>
// Generated at compile time
#include "jsonapi-wrappers.h"
JsonApiServer::JsonApiServer(
uint16_t port, const std::function<void(int)> shutdownCallback) :
mPort(port), mShutdownCallback(shutdownCallback)
mPort(port), mShutdownCallback(shutdownCallback), notifyClientWrapper(*this)
{
registerHandler("/jsonApiServer/shutdown",
[this](const std::shared_ptr<restbed::Session>)
[this](const std::shared_ptr<rb::Session>)
{
shutdown();
});
registerHandler("/jsonApiServer/notifications",
[this](const std::shared_ptr<rb::Session> session)
{
const auto headers = std::multimap<std::string, std::string>
{
{ "Connection", "keep-alive" },
{ "Cache-Control", "no-cache" },
{ "Content-Type", "text/event-stream" },
};
session->yield(rb::OK, headers,
[this](const std::shared_ptr<rb::Session> session)
{
notifySessions.push_back(session);
} );
} );
// Generated at compile time
#include "jsonapi-register.inl"
}
@ -59,3 +80,47 @@ void JsonApiServer::shutdown(int exitCode)
mService.stop();
mShutdownCallback(exitCode);
}
void JsonApiServer::cleanClosedNotifySessions()
{
notifySessions.erase(
std::remove_if(
notifySessions.begin(), notifySessions.end(),
[](const std::shared_ptr<rb::Session> &s)
{ return s->is_closed(); } ), notifySessions.end());
}
JsonApiServer::NotifyClientWrapper::NotifyClientWrapper(JsonApiServer& parent) :
NotifyClient(), mJsonApiServer(parent)
{
rsNotify->registerNotifyClient(static_cast<NotifyClient*>(this));
}
void JsonApiServer::NotifyClientWrapper::notifyTurtleSearchResult(
uint32_t searchId, const std::list<TurtleFileInfo>& files )
{
mJsonApiServer.cleanClosedNotifySessions();
RsGenericSerializer::SerializeContext cAns;
RsJson& jAns(cAns.mJson);
// serialize parameters and method name to JSON
{
std::string methodName("NotifyClient/notifyTurtleSearchResult");
std::list<TurtleFileInfo> filesCopy(files);
RsGenericSerializer::SerializeContext& ctx(cAns);
RsGenericSerializer::SerializeJob j(RsGenericSerializer::TO_JSON);
RS_SERIAL_PROCESS(methodName);
RS_SERIAL_PROCESS(searchId);
// RS_SERIAL_PROCESS(filesCopy);
}
rapidjson::StringBuffer buffer;
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
jAns.Accept(writer);
std::string message(buffer.GetString(), buffer.GetSize());
message.insert(0, "data: "); message.append("\n\n");
for(auto session : mJsonApiServer.notifySessions)
session->yield(message);
}

View file

@ -19,16 +19,12 @@
#include <string>
#include <memory>
#include <restbed>
#include <rapid_json/document.h>
#include "retroshare/rsgxschannels.h"
#include "serialiser/rstypeserializer.h"
#include "util/rsthreads.h"
#include "retroshare/rsnotify.h"
namespace rb = restbed;
void apiVersionHandler(const std::shared_ptr<rb::Session> session);
void createChannelHandler(const std::shared_ptr<rb::Session> session);
/**
* Simple usage
@ -74,5 +70,20 @@ private:
uint16_t mPort;
rb::Service mService;
const std::function<void(int)> mShutdownCallback;
std::list<std::shared_ptr<rb::Session> > notifySessions;
void cleanClosedNotifySessions();
struct NotifyClientWrapper : NotifyClient
{
NotifyClientWrapper(JsonApiServer& parent);
void notifyTurtleSearchResult(
uint32_t searchId, const std::list<TurtleFileInfo>& files);
private:
JsonApiServer& mJsonApiServer;
};
NotifyClientWrapper notifyClientWrapper;
};