#pragma once #include #include #include #include #include #include #include #include #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 peer, PubSubResult result, const std::string &resultStr)>; using PubSubReceiveDataCallback = std::function peer, const void *data, const usize size)>; using PubSubSendDataCallback = std::function; 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 &peer, std::shared_ptr> 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); void receiveData(); int receiveDataFromPeer(const int socket, char *output); bool removePeer(int peerSocket); private: u16 port; int eid; std::unordered_map> peers; std::thread receiveDataThread; std::mutex peersMutex; bool alive; }; }