#ifndef REMOTE_SERVER_H #define REMOTE_SERVER_H #include <Communicate.h> #include <InfoCommunicate.hpp> #include <Util.h> #include <array> #include <chrono> #include <cstdint> #include <memory> #include <shared_mutex> #include <thread> #include <unordered_map> #include <wx/event.h> #include <wx/evtloop.h> #include <wx/socket.h> #include <wx/wx.h> using highClock_t = std::chrono::time_point<std::chrono::high_resolution_clock>; using sockPtr = std::shared_ptr<wxSocketBase>; struct TranClient { sockPtr wxSock; MutBuffer buffer; int64_t onlineTime; std::string name; highClock_t lastRecvTime; std::array<char, GBUFFER_SIZE> buf; }; class RelayServer : public wxEvtHandler { public: RelayServer(); public: bool Init(const wxString& ip, unsigned short port); int Run(); private: void OnServerEvent(wxSocketEvent& event); void thClientThread(const std::shared_ptr<wxSocketBase>& wxSock, const wxString& id); bool Forword(const sockPtr& wxSock, FrameBuffer* buf); void ReplyRequest(const sockPtr& wxSock, FrameBuffer* frame); void ClearClient(const wxString& id); private: bool RpyOnline(const sockPtr& wxSock, FrameBuffer* frame); bool RpyForwordFailed(const sockPtr& wxSock, FrameBuffer* frame); private: template <typename T> bool Send(const sockPtr& wxSock, const T& info, FrameBufferType type, const std::string& fid, const std::string& tid) { std::stringstream ss; cereal::BinaryOutputArchive archive(ss); archive(info); auto buf = std::make_shared<FrameBuffer>(); buf->fid = fid; buf->tid = tid; std::swap(buf->fid, buf->tid); buf->dataConst = ss.view().data(); buf->len = ss.str().size(); buf->dataType = type; return Send(wxSock, buf.get()); } bool Send(const sockPtr& wxSock, FrameBuffer* buf); private: bool thRun_{false}; std::string strID_; wxWindowID serverId_; std::shared_mutex clientsMutex_; std::unique_ptr<wxSocketServer> server_; std::unordered_map<wxString, std::thread> threads_; std::unordered_map<wxString, std::shared_ptr<TranClient>> clients_; }; #endif // REMOTE_SERVER_H