You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
lokinet/libabyss/include/abyss/client.hpp

128 lines
3.0 KiB
C++

#ifndef ABYSS_CLIENT_HPP
#define ABYSS_CLIENT_HPP
#include <ev/ev.h>
#include <util/json.hpp>
#include <util/string_view.hpp>
#include <abyss/http.hpp>
#include <deque>
#include <functional>
#include <list>
#include <memory>
#include <string>
#include <unordered_map>
#include <atomic>
namespace abyss
{
namespace http
{
using RPC_Method_t = std::string;
using RPC_Params = nlohmann::json;
using RPC_Response = nlohmann::json;
using Headers_t = std::unordered_multimap<std::string, std::string>;
using Response = RequestHeader;
struct ConnImpl;
/// jsonrpc response handler for client
struct IRPCClientHandler
{
IRPCClientHandler(ConnImpl* impl);
virtual ~IRPCClientHandler();
/// handle response from rpc server
/// return true on successful handling
/// return false on errors while handling
virtual bool
HandleResponse(RPC_Response response) = 0;
/// populate http request headers
virtual void
PopulateReqHeaders(Headers_t& hdr) = 0;
/// handle fatal internal error while doing request
virtual void
HandleError() = 0;
/// return true if we should close
bool
ShouldClose() const;
/// close underlying connection
void
Close() const;
private:
ConnImpl* m_Impl;
};
/// jsonrpc client
struct JSONRPC
{
using HandlerFactory = std::function<IRPCClientHandler*(ConnImpl*)>;
JSONRPC();
~JSONRPC();
/// start runing on event loop async
/// return true on success otherwise return false
bool
RunAsync(llarp_ev_loop_ptr loop, const std::string& endpoint);
/// must be called after RunAsync returns true
/// queue a call for rpc
void
QueueRPC(RPC_Method_t method, RPC_Params params, HandlerFactory createHandler);
/// drop all pending calls on the floor
void
DropAllCalls();
/// close all connections and stop operation
void
Stop();
/// handle new outbound connection
void
Connected(llarp_tcp_conn* conn);
/// flush queued rpc calls
void
Flush();
std::string username;
std::string password;
private:
struct Call
{
Call(RPC_Method_t&& m, RPC_Params&& p, HandlerFactory&& f)
: method(std::move(m)), params(std::move(p)), createHandler(std::move(f))
{
}
RPC_Method_t method;
RPC_Params params;
HandlerFactory createHandler;
};
static void
OnConnected(llarp_tcp_connecter* connect, llarp_tcp_conn* conn);
static void
OnConnectFail(llarp_tcp_connecter* connect);
static void
OnTick(llarp_tcp_connecter* connect);
std::atomic<bool> m_Run;
llarp_tcp_connecter m_connect;
llarp_ev_loop_ptr m_Loop;
std::deque<Call> m_PendingCalls;
std::list<std::unique_ptr<IRPCClientHandler>> m_Conns;
};
} // namespace http
} // namespace abyss
#endif