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
|
#pragma once
#include <unordered_map>
#include <functional>
#include <string>
#include <memory>
#include <thread>
#include <mutex>
#include <vector>
#include <stdexcept>
#include "IpAddress.hpp"
#include "../types.hpp"
#include "../utils.hpp"
namespace sibs
{
class SocketCreateException : public std::runtime_error
{
public:
SocketCreateException(const std::string &errMsg) : std::runtime_error(errMsg) {}
};
enum class PubSubResult
{
OK,
ERROR
};
struct DirectConnectionPeer;
using PubSubConnectCallback = std::function<void(std::shared_ptr<DirectConnectionPeer> peer, PubSubResult result, const std::string &resultStr)>;
using PubSubReceiveDataCallback = std::function<void(std::shared_ptr<DirectConnectionPeer> peer, const void *data, const usize size)>;
using PubSubSendDataCallback = std::function<void(PubSubResult result, const std::string &resultStr)>;
struct DirectConnectionPeer
{
int socket;
Ipv4 address;
PubSubReceiveDataCallback receiveDataCallbackFunc;
};
class DirectConnections
{
DISABLE_COPY(DirectConnections)
friend class BootstrapNode;
public:
DirectConnections(u16 port = 27137);
~DirectConnections();
// Throws ConnectionException on error
void connectServer(const Ipv4 &address, PubSubConnectCallback connectCallbackFunc, PubSubReceiveDataCallback receiveDataCallbackFunc);
// Throws ConnectionException on error
void connect(const Ipv4 &address, PubSubConnectCallback connectCallbackFunc, PubSubReceiveDataCallback receiveDataCallbackFunc);
void send(const std::shared_ptr<DirectConnectionPeer> &peer, std::shared_ptr<std::vector<u8>> data, PubSubSendDataCallback sendDataCallbackFunc = nullptr);
protected:
int createSocket(const Ipv4 &addressToBind, bool rendezvous, bool reuseAddr, bool bind = true);
private:
void connect(const Ipv4 &address, bool rendezvous, bool reuseAddr, PubSubConnectCallback connectCallbackFunc, PubSubReceiveDataCallback receiveDataCallbackFunc, bool bind);
void removeDisconnectedPeers();
void receiveData();
int receiveDataFromPeer(const int socket, char *output, usize *receivedTotalSize);
bool removePeer(int peerSocket);
private:
u16 port;
int eid;
std::unordered_map<int, std::shared_ptr<DirectConnectionPeer>> peers;
std::thread receiveDataThread;
std::mutex peersMutex;
bool alive;
};
}
|