#include "ClientCore.h" #include <InfoEnhance.hpp> ClientCore::ClientCore() { socket_ = new wxSocketClient(); } ClientCore::~ClientCore() { Disconnect(); thRun_ = false; if (recvThread_.joinable()) { recvThread_.join(); } } bool ClientCore::Connect(const wxString& host, uint16_t port) { wxIPV4address addr; addr.Hostname(host); addr.Service(port); socket_->SetEventHandler(*this, wxID_ANY); socket_->SetNotify(wxSOCKET_LOST_FLAG); socket_->SetFlags(wxSOCKET_BLOCK); socket_->Notify(true); if (socket_->IsConnected()) { return true; } if (!socket_->Connect(addr)) { return false; } Bind(wxEVT_SOCKET, &ClientCore::OnSocketEvent, this); if (recvThread_.joinable()) { recvThread_.join(); } thRun_ = true; recvThread_ = std::thread(&ClientCore::Recv, this); return true; } void ClientCore::Disconnect() { socket_->Close(); } wxString ClientCore::GetErr() const { return err_; } wxString ClientCore::GetOwnId() const { return id_; } bool ClientCore::IsOk() { return socket_->IsConnected(); } void ClientCore::SetLogCallback(const std::function<void(const wxString&)>& callback) { logCall_ = callback; } bool ClientCore::ReqOnline() { InfoCommunicate infoCommunicate; if (!Send<InfoCommunicate>(infoCommunicate, FBT_SER_MSG_ASKCLIENTS)) { return false; } return true; } void ClientCore::ReqOnlineCallback(const std::function<void(const InfoClientVec&)>& callback) { onlineCallback_ = callback; } void ClientCore::SetHomeCallback(const std::function<void(const wxString&)>& callback) { homeCall_ = callback; } void ClientCore::SetDirFileCallback(const std::function<void(const DirFileInfoVec&)>& callback) { dirFileCall_ = callback; } bool ClientCore::AskDirectory(const wxString& id, const wxString& path, DirFileInfoVec& dirInfoVec) { return false; } void ClientCore::OnSocketEvent(wxSocketEvent& event) { auto* sock = event.GetSocket(); auto type = event.GetSocketEvent(); switch (type) { case wxSOCKET_LOST: { logCall_(wxString::Format(_("Lost connection to server."))); break; } default: logCall_(wxString::Format(_T("No Handled Type: %d."), static_cast<int>(type))); break; } } void ClientCore::UseFrame(FrameBuffer* buf) { std::stringstream ss; switch (buf->dataType) { case FBT_SER_MSG_ASKCLIENTS: { InfoClientVec vec; ZeroCopyInput input(buf->dataMut, buf->len); input.archive() >> vec; logCall_(wxString::Format(_("Online clients: %d."), static_cast<int>(vec.vec.size()))); if (onlineCallback_) { onlineCallback_(vec); } break; } case FBT_SER_MSG_YOURID: { InfoCommunicate info; ZeroCopyInput input(buf->dataMut, buf->len); input.archive() >> info; id_ = wxString(info.msg.c_str()); logCall_(wxString::Format(_("Your id is %s."), id_)); break; } case FBT_SER_MSG_RESPONSE: { InfoCommunicate info; break; } case FBT_CLI_ASK_HOME: { InfoCommunicate info; wxString home = wxGetHomeDir(); info.msg = home.ToStdWstring(); Send<InfoCommunicate>(info, FBT_CLI_ANS_HOME, buf->fid); break; } case FBT_CLI_ANS_HOME: { InfoCommunicate info; ZeroCopyInput input(buf->dataMut, buf->len); input.archive() >> info; if (homeCall_) { homeCall_(wxString(info.msg.c_str())); } break; } case FBT_CLI_ASK_DIRFILE: { InfoCommunicate info; ZeroCopyInput input(buf->dataMut, buf->len); input.archive() >> info; DirFileInfoVec vec; if (!cf_.GetDirFiles(info.msg, vec)) { break; } Send<DirFileInfoVec>(vec, FBT_CLI_ANS_DIRFILE, buf->fid); break; } case FBT_CLI_ANS_DIRFILE: { DirFileInfoVec vec; ZeroCopyInput input(buf->dataMut, buf->len); input.archive() >> vec; if (dirFileCall_) { dirFileCall_(vec); } break; } default: break; } } void ClientCore::HeartBeat() { } void ClientCore::Recv() { while (thRun_) { socket_->Read(buf_.data(), GBUFFER_SIZE); auto len = socket_->LastCount(); if (len == 0) { break; } buffer_.Push(buf_.data(), len); while (true) { auto* frame = Communicate::ParseBuffer(buffer_); if (frame == nullptr) { break; } UseFrame(frame); delete frame; } } } bool ClientCore::Send(FrameBuffer* buf) { if (buf == nullptr) { return false; } char* od = nullptr; int odLen = 0; if (!Communicate::PackBuffer(buf, &od, odLen)) { return false; } socket_->Write(od, odLen); if (socket_->Error()) { delete[] od; wxLogError(wxT("Send error: %s"), socket_->LastError()); return false; } delete[] od; return true; }