mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
Experiment of notification via NotifyClient + JSON API
This commit is contained in:
parent
130007b578
commit
1bc518041c
@ -18,19 +18,40 @@
|
|||||||
|
|
||||||
#include "jsonapi.h"
|
#include "jsonapi.h"
|
||||||
|
|
||||||
|
#include <rapid_json/document.h>
|
||||||
|
#include <rapid_json/writer.h>
|
||||||
|
#include <rapid_json/stringbuffer.h>
|
||||||
|
|
||||||
// Generated at compile time
|
// Generated at compile time
|
||||||
#include "jsonapi-wrappers.h"
|
#include "jsonapi-wrappers.h"
|
||||||
|
|
||||||
JsonApiServer::JsonApiServer(
|
JsonApiServer::JsonApiServer(
|
||||||
uint16_t port, const std::function<void(int)> shutdownCallback) :
|
uint16_t port, const std::function<void(int)> shutdownCallback) :
|
||||||
mPort(port), mShutdownCallback(shutdownCallback)
|
mPort(port), mShutdownCallback(shutdownCallback), notifyClientWrapper(*this)
|
||||||
{
|
{
|
||||||
registerHandler("/jsonApiServer/shutdown",
|
registerHandler("/jsonApiServer/shutdown",
|
||||||
[this](const std::shared_ptr<restbed::Session>)
|
[this](const std::shared_ptr<rb::Session>)
|
||||||
{
|
{
|
||||||
shutdown();
|
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
|
// Generated at compile time
|
||||||
#include "jsonapi-register.inl"
|
#include "jsonapi-register.inl"
|
||||||
}
|
}
|
||||||
@ -59,3 +80,47 @@ void JsonApiServer::shutdown(int exitCode)
|
|||||||
mService.stop();
|
mService.stop();
|
||||||
mShutdownCallback(exitCode);
|
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);
|
||||||
|
}
|
||||||
|
@ -19,16 +19,12 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <restbed>
|
#include <restbed>
|
||||||
#include <rapid_json/document.h>
|
|
||||||
|
|
||||||
#include "retroshare/rsgxschannels.h"
|
|
||||||
#include "serialiser/rstypeserializer.h"
|
|
||||||
#include "util/rsthreads.h"
|
#include "util/rsthreads.h"
|
||||||
|
#include "retroshare/rsnotify.h"
|
||||||
|
|
||||||
namespace rb = restbed;
|
namespace rb = restbed;
|
||||||
|
|
||||||
void apiVersionHandler(const std::shared_ptr<rb::Session> session);
|
|
||||||
void createChannelHandler(const std::shared_ptr<rb::Session> session);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple usage
|
* Simple usage
|
||||||
@ -74,5 +70,20 @@ private:
|
|||||||
uint16_t mPort;
|
uint16_t mPort;
|
||||||
rb::Service mService;
|
rb::Service mService;
|
||||||
const std::function<void(int)> mShutdownCallback;
|
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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -181,7 +181,7 @@ class RsFeedItem
|
|||||||
// This mechanism can be used in plugins, new services, etc.
|
// This mechanism can be used in plugins, new services, etc.
|
||||||
//
|
//
|
||||||
|
|
||||||
class NotifyClient ;
|
struct NotifyClient;
|
||||||
|
|
||||||
class RsNotify
|
class RsNotify
|
||||||
{
|
{
|
||||||
@ -206,44 +206,42 @@ class RsNotify
|
|||||||
virtual bool setDisableAskPassword (const bool /*bValue*/) { return false ; }
|
virtual bool setDisableAskPassword (const bool /*bValue*/) { return false ; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class NotifyClient
|
struct NotifyClient
|
||||||
{
|
{
|
||||||
public:
|
NotifyClient() {}
|
||||||
NotifyClient() {}
|
virtual ~NotifyClient() {}
|
||||||
virtual ~NotifyClient() {}
|
|
||||||
|
|
||||||
virtual void notifyListPreChange (int /* list */, int /* type */) {}
|
virtual void notifyListPreChange (int /* list */, int /* type */) {}
|
||||||
virtual void notifyListChange (int /* list */, int /* type */) {}
|
virtual void notifyListChange (int /* list */, int /* type */) {}
|
||||||
virtual void notifyErrorMsg (int /* list */, int /* sev */, std::string /* msg */) {}
|
virtual void notifyErrorMsg (int /* list */, int /* sev */, std::string /* msg */) {}
|
||||||
virtual void notifyChatMessage (const ChatMessage& /* msg */) {}
|
virtual void notifyChatMessage (const ChatMessage& /* msg */) {}
|
||||||
virtual void notifyChatStatus (const ChatId& /* chat_id */, const std::string& /* status_string */) {}
|
virtual void notifyChatStatus (const ChatId& /* chat_id */, const std::string& /* status_string */) {}
|
||||||
virtual void notifyChatCleared (const ChatId& /* chat_id */) {}
|
virtual void notifyChatCleared (const ChatId& /* chat_id */) {}
|
||||||
virtual void notifyChatLobbyEvent (uint64_t /* lobby id */, uint32_t /* event type */ ,const RsGxsId& /* nickname */,const std::string& /* any string */) {}
|
virtual void notifyChatLobbyEvent (uint64_t /* lobby id */, uint32_t /* event type */ ,const RsGxsId& /* nickname */,const std::string& /* any string */) {}
|
||||||
virtual void notifyChatLobbyTimeShift (int /* time_shift*/) {}
|
virtual void notifyChatLobbyTimeShift (int /* time_shift*/) {}
|
||||||
virtual void notifyCustomState (const std::string& /* peer_id */, const std::string& /* status_string */) {}
|
virtual void notifyCustomState (const std::string& /* peer_id */, const std::string& /* status_string */) {}
|
||||||
virtual void notifyHashingInfo (uint32_t /* type */, const std::string& /* fileinfo */) {}
|
virtual void notifyHashingInfo (uint32_t /* type */, const std::string& /* fileinfo */) {}
|
||||||
virtual void notifyTurtleSearchResult (uint32_t /* search_id */, const std::list<TurtleFileInfo>& /* files */) {}
|
virtual void notifyTurtleSearchResult (uint32_t /* search_id */, const std::list<TurtleFileInfo>& /* files */) {}
|
||||||
#warning MISSING CODE HERE
|
#warning MISSING CODE HERE
|
||||||
// virtual void notifyTurtleSearchResult (uint32_t /* search_id */, const std::list<TurtleGxsInfo >& /* groups */) {}
|
// virtual void notifyTurtleSearchResult (uint32_t /* search_id */, const std::list<TurtleGxsInfo >& /* groups */) {}
|
||||||
virtual void notifyPeerHasNewAvatar (std::string /* peer_id */) {}
|
virtual void notifyPeerHasNewAvatar (std::string /* peer_id */) {}
|
||||||
virtual void notifyOwnAvatarChanged () {}
|
virtual void notifyOwnAvatarChanged () {}
|
||||||
virtual void notifyOwnStatusMessageChanged () {}
|
virtual void notifyOwnStatusMessageChanged () {}
|
||||||
virtual void notifyDiskFull (uint32_t /* location */, uint32_t /* size limit in MB */) {}
|
virtual void notifyDiskFull (uint32_t /* location */, uint32_t /* size limit in MB */) {}
|
||||||
virtual void notifyPeerStatusChanged (const std::string& /* peer_id */, uint32_t /* status */) {}
|
virtual void notifyPeerStatusChanged (const std::string& /* peer_id */, uint32_t /* status */) {}
|
||||||
virtual void notifyGxsChange (const RsGxsChanges& /* changes */) {}
|
virtual void notifyGxsChange (const RsGxsChanges& /* changes */) {}
|
||||||
virtual void notifyConnectionWithoutCert () {}
|
virtual void notifyConnectionWithoutCert () {}
|
||||||
|
|
||||||
/* one or more peers has changed the states */
|
/* one or more peers has changed the states */
|
||||||
virtual void notifyPeerStatusChangedSummary () {}
|
virtual void notifyPeerStatusChangedSummary () {}
|
||||||
virtual void notifyDiscInfoChanged () {}
|
virtual void notifyDiscInfoChanged () {}
|
||||||
|
|
||||||
virtual bool askForDeferredSelfSignature (const void * /* data */, const uint32_t /* len */, unsigned char * /* sign */, unsigned int * /* signlen */,int& signature_result , std::string /*reason = ""*/) { signature_result = false ;return true; }
|
virtual bool askForDeferredSelfSignature (const void * /* data */, const uint32_t /* len */, unsigned char * /* sign */, unsigned int * /* signlen */,int& signature_result , std::string /*reason = ""*/) { signature_result = false ;return true; }
|
||||||
virtual void notifyDownloadComplete (const std::string& /* fileHash */) {}
|
virtual void notifyDownloadComplete (const std::string& /* fileHash */) {}
|
||||||
virtual void notifyDownloadCompleteCount (uint32_t /* count */) {}
|
virtual void notifyDownloadCompleteCount (uint32_t /* count */) {}
|
||||||
virtual void notifyHistoryChanged (uint32_t /* msgId */, int /* type */) {}
|
virtual void notifyHistoryChanged (uint32_t /* msgId */, int /* type */) {}
|
||||||
|
|
||||||
virtual bool askForPassword (const std::string& /* title */, const std::string& /* key_details */, bool /* prev_is_bad */, std::string& /* password */,bool& /* cancelled */ ) { return false ;}
|
|
||||||
virtual bool askForPluginConfirmation (const std::string& /* plugin_filename */, const std::string& /* plugin_file_hash */,bool /* first_time */) { return false ;}
|
|
||||||
|
|
||||||
|
virtual bool askForPassword (const std::string& /* title */, const std::string& /* key_details */, bool /* prev_is_bad */, std::string& /* password */,bool& /* cancelled */ ) { return false ;}
|
||||||
|
virtual bool askForPluginConfirmation (const std::string& /* plugin_filename */, const std::string& /* plugin_file_hash */,bool /* first_time */) { return false ;}
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
@ -29,12 +29,18 @@
|
|||||||
#include "serialiser/rstlvbinary.h"
|
#include "serialiser/rstlvbinary.h"
|
||||||
#include "retroshare/rstypes.h"
|
#include "retroshare/rstypes.h"
|
||||||
#include "retroshare/rsgxsifacetypes.h"
|
#include "retroshare/rsgxsifacetypes.h"
|
||||||
|
#include "serialiser/rsserializable.h"
|
||||||
|
|
||||||
namespace RsRegularExpression { class LinearizedExpression ; }
|
namespace RsRegularExpression { class LinearizedExpression ; }
|
||||||
class RsTurtleClientService ;
|
class RsTurtleClientService ;
|
||||||
|
|
||||||
class RsTurtle;
|
class RsTurtle;
|
||||||
extern RsTurtle *rsTurtle ;
|
|
||||||
|
/**
|
||||||
|
* Pointer to global instance of RsTurtle service implementation
|
||||||
|
* @jsonapi{development}
|
||||||
|
*/
|
||||||
|
extern RsTurtle* rsTurtle;
|
||||||
|
|
||||||
typedef uint32_t TurtleRequestId ;
|
typedef uint32_t TurtleRequestId ;
|
||||||
typedef RsPeerId TurtleVirtualPeerId;
|
typedef RsPeerId TurtleVirtualPeerId;
|
||||||
@ -42,11 +48,20 @@ typedef RsPeerId TurtleVirtualPeerId;
|
|||||||
// This is the structure used to send back results of the turtle search
|
// This is the structure used to send back results of the turtle search
|
||||||
// to the notifyBase class, or send info to the GUI.
|
// to the notifyBase class, or send info to the GUI.
|
||||||
|
|
||||||
struct TurtleFileInfo
|
struct TurtleFileInfo //: RsSerializable
|
||||||
{
|
{
|
||||||
RsFileHash hash ;
|
RsFileHash hash;
|
||||||
std::string name ;
|
std::string name;
|
||||||
uint64_t size ;
|
uint64_t size;
|
||||||
|
/*
|
||||||
|
/// @see RsSerializable::serial_process
|
||||||
|
void serial_process( RsGenericSerializer::SerializeJob j,
|
||||||
|
RsGenericSerializer::SerializeContext& ctx )
|
||||||
|
{
|
||||||
|
RS_SERIAL_PROCESS(hash);
|
||||||
|
RS_SERIAL_PROCESS(name);
|
||||||
|
RS_SERIAL_PROCESS(size);
|
||||||
|
}*/
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TurtleTunnelRequestDisplayInfo
|
struct TurtleTunnelRequestDisplayInfo
|
||||||
@ -90,7 +105,7 @@ class TurtleTrafficStatisticsInfo
|
|||||||
//
|
//
|
||||||
class RsTurtle
|
class RsTurtle
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RsTurtle() {}
|
RsTurtle() {}
|
||||||
virtual ~RsTurtle() {}
|
virtual ~RsTurtle() {}
|
||||||
|
|
||||||
@ -106,7 +121,9 @@ class RsTurtle
|
|||||||
// the request id, which will be further used by the gui to store results
|
// the request id, which will be further used by the gui to store results
|
||||||
// as they come back.
|
// as they come back.
|
||||||
//
|
//
|
||||||
virtual TurtleRequestId turtleSearch(unsigned char *search_bin_data,uint32_t search_bin_data_len,RsTurtleClientService *client_service) =0;
|
virtual TurtleRequestId turtleSearch(
|
||||||
|
unsigned char *search_bin_data, uint32_t search_bin_data_len,
|
||||||
|
RsTurtleClientService* client_service ) = 0;
|
||||||
|
|
||||||
// Initiates tunnel handling for the given file hash. tunnels. Launches
|
// Initiates tunnel handling for the given file hash. tunnels. Launches
|
||||||
// an exception if an error occurs during the initialization process. The
|
// an exception if an error occurs during the initialization process. The
|
||||||
|
@ -244,9 +244,10 @@ bool getRawString(const void *data, uint32_t size, uint32_t *offset, std::string
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* check there is space for string */
|
/* check there is space for string */
|
||||||
if(len > size || size-len < *offset) // better than if(size < *offset + len) because it avoids integer overflow
|
if(len > size || size-len < *offset) // better than if(size < *offset + len) because it avoids integer overflow
|
||||||
{
|
{
|
||||||
std::cerr << "getRawString() not enough size" << std::endl;
|
std::cerr << "getRawString() not enough size" << std::endl;
|
||||||
|
print_stacktrace();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
uint8_t *buf = &(((uint8_t *) data)[*offset]);
|
uint8_t *buf = &(((uint8_t *) data)[*offset]);
|
||||||
|
Loading…
Reference in New Issue
Block a user