forked from HarbourMasters/Ghostship
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSatellaClient.h
More file actions
81 lines (61 loc) · 2.25 KB
/
Copy pathSatellaClient.h
File metadata and controls
81 lines (61 loc) · 2.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#pragma once
#ifdef USE_NETWORKING
#include <condition_variable>
#include <cstdint>
#include <memory>
#include <mutex>
#include <string>
#include <vector>
#include <atomic>
#include <ixwebsocket/IXWebSocketMessage.h>
#define SATELLA_HOST "wss://satella.net64.dev"
namespace Satella {
enum class Phase { Idle, Connecting, FetchingKeys, Done };
class IPacket {
public:
virtual ~IPacket() = default;
virtual const char* GetRoute() const = 0;
virtual void OnResponse(int16_t status, const std::string& body) = 0;
virtual bool IsBlocking() const { return false; }
virtual bool IsSubscription() const { return false; }
virtual void OnPush(int16_t status, uint8_t packetType, const std::string& body) {}
};
class Client {
public:
static Client& Instance();
void Register(std::unique_ptr<IPacket> packet);
void Execute(const std::string& url = SATELLA_HOST);
Phase GetPhase() const { return mPhase.load(std::memory_order_relaxed); }
// Register a subscription packet onto an already-running connection.
// If not yet connected, the packet is queued for the next Execute() call.
void RegisterLive(std::unique_ptr<IPacket> packet);
// Send a raw binary frame: HM64 header + route + 4-byte body length + body.
// No-op if the socket is not open.
void SendRaw(const std::string& route, const void* data, size_t size);
private:
Client() = default;
~Client();
void Connect(const std::string& url);
void SendAndReceive(IPacket& packet);
void OnMessage(const ix::WebSocketMessagePtr& msg);
std::vector<std::unique_ptr<IPacket>> mPackets;
std::vector<IPacket*> mSubscriptions;
std::string mUrl;
std::mutex mMtx;
std::condition_variable mCv;
std::atomic<Phase> mPhase{ Phase::Idle };
bool mConnected = false;
bool mWaitingForResponse = false;
bool mResponseReady = false;
bool mResponseValid = false;
int16_t mResponseStatus = 0;
std::string mResponseBody;
};
template<typename T>
struct PacketAutoReg {
PacketAutoReg() { Client::Instance().Register(std::make_unique<T>()); }
};
#define SATELLA_REGISTER_PACKET(T) \
static ::Satella::PacketAutoReg<T> _satella_pkt_##T
} // namespace Satella
#endif