#pragma once #include #include #include #include #include #include #include #include "IpAddress.hpp" #include "../types.hpp" #include "../utils.hpp" namespace sibs { class ConnectionException : public std::runtime_error { public: ConnectionException(const std::string &errMsg) : std::runtime_error(errMsg) {} }; class SendException : public std::runtime_error { public: SendException(const std::string &errMsg) : std::runtime_error(errMsg) {} }; enum class PubSubConnectResult { OK, ERROR }; using PubSubConnectCallback = std::function; using PubSubReceiveDataCallback = std::function; struct DirectConnectionPeer { int socket; PubSubReceiveDataCallback receiveDataCallbackFunc; }; class DirectConnections { DISABLE_COPY(DirectConnections) friend class BootstrapNode; public: DirectConnections(u16 port = 27137); ~DirectConnections(); // Throws ConnectionException on error std::shared_ptr connect(const Ipv4 &address, PubSubReceiveDataCallback receiveDataCallbackFunc); // Throws SendException on error void send(const std::shared_ptr &peer, const void *data, const usize size); protected: int createSocket(const Ipv4 &addressToBind, bool rendezvous, bool reuseAddr); private: void receiveData(); bool receiveDataFromPeer(const int socket, char *output); private: u16 port; int eid; std::unordered_map> peers; std::thread receiveDataThread; std::mutex peersMutex; bool alive; }; }