mirror of
https://github.com/vdemydiuk/mtapi.git
synced 2026-07-28 19:17:48 +00:00
Added new projects of new RPC core: MyClient and MtServivce
This commit is contained in:
Executable
+224
@@ -0,0 +1,224 @@
|
||||
// MtService.cpp : Defines the functions for the static library.
|
||||
//
|
||||
|
||||
#include "pch.h"
|
||||
#include "framework.h"
|
||||
#include "MtService.h"
|
||||
|
||||
#include "MtExpert.h"
|
||||
#include "LogConfigurator.h"
|
||||
#include "MtServer.h"
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
// MtService
|
||||
//--------------------------------------------------------------------------------
|
||||
|
||||
class MtServiceImpl
|
||||
{
|
||||
public:
|
||||
MtServiceImpl();
|
||||
~MtServiceImpl();
|
||||
|
||||
void InitExpert(int port, int handle, std::unique_ptr<MetaTraderHandler> mt_handler);
|
||||
void DeinitExpert(int handle);
|
||||
|
||||
void SendEvent(int handle, int event_type, const std::string& payload);
|
||||
void SendResponse(int handle, const std::string& payload);
|
||||
|
||||
int GetCommandType(int handle);
|
||||
std::string GetCommandPayload(int handle);
|
||||
|
||||
void LogError(const std::string& error);
|
||||
|
||||
private:
|
||||
void OnServerStopped(unsigned short port);
|
||||
void ThreadProc();
|
||||
|
||||
Logger log_{ "MtService" };
|
||||
boost::asio::io_context context_;
|
||||
std::unique_ptr<boost::asio::io_context::work> work_;
|
||||
std::thread thread_;
|
||||
|
||||
std::unordered_map<int, std::unique_ptr<MtExpert>> experts_;
|
||||
std::unordered_map<unsigned short, std::shared_ptr<MtServer>> servers_;
|
||||
};
|
||||
|
||||
MtServiceImpl::MtServiceImpl()
|
||||
: work_(new boost::asio::io_context::work(context_))
|
||||
, thread_(&MtServiceImpl::ThreadProc, this)
|
||||
{
|
||||
log_.Debug("%s: service created", __FUNCTION__);
|
||||
}
|
||||
|
||||
MtServiceImpl::~MtServiceImpl()
|
||||
{
|
||||
log_.Trace("%s: destructor started", __FUNCTION__);
|
||||
|
||||
boost::asio::post(context_, [this]() {
|
||||
if (experts_.size() > 0)
|
||||
{
|
||||
for (auto& e : experts_)
|
||||
e.second->Deinit();
|
||||
experts_.clear();
|
||||
}
|
||||
});
|
||||
work_.reset();
|
||||
if (thread_.joinable())
|
||||
thread_.join();
|
||||
|
||||
log_.Debug("%s: service destroyed", __FUNCTION__);
|
||||
}
|
||||
|
||||
void MtServiceImpl::InitExpert(int port, int handle, std::unique_ptr<MetaTraderHandler> mt_handler)
|
||||
{
|
||||
log_.Debug("%s: port = %d, handle = %d", __FUNCTION__, port, handle);
|
||||
|
||||
boost::asio::post(context_, [port, handle, mt_h = std::move(mt_handler), this]() mutable {
|
||||
auto expert = std::make_unique<MtExpert>(handle, std::move(mt_h));
|
||||
if (servers_.count(port) == 0)
|
||||
{
|
||||
auto server = std::make_shared<MtServer>(context_, port);
|
||||
server->OnStopped.connect(boost::bind(&MtServiceImpl::OnServerStopped, this, std::placeholders::_1));
|
||||
servers_[port] = server;
|
||||
}
|
||||
|
||||
servers_[port]->AddExpert(handle, expert.get());
|
||||
experts_[handle] = std::move(expert);
|
||||
});
|
||||
}
|
||||
|
||||
void MtServiceImpl::DeinitExpert(int handle)
|
||||
{
|
||||
log_.Debug("%s: handle = %d", __FUNCTION__, handle);
|
||||
|
||||
boost::asio::post(context_, [handle, this]() {
|
||||
if (experts_.count(handle) > 0)
|
||||
{
|
||||
experts_[handle]->Deinit();
|
||||
experts_.erase(handle);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void MtServiceImpl::SendEvent(int handle, int event_type, const std::string& payload)
|
||||
{
|
||||
log_.Trace("%s: handle = %d, event_type = %d, payload = %s", __FUNCTION__, handle, event_type, payload.c_str());
|
||||
|
||||
boost::asio::post(context_, [handle, event_type, payload = payload, this]() {
|
||||
if (experts_.count(handle) > 0)
|
||||
experts_[handle]->SendEvent(event_type, payload);
|
||||
});
|
||||
}
|
||||
|
||||
void MtServiceImpl::SendResponse(int handle, const std::string& payload)
|
||||
{
|
||||
log_.Trace("%s: handle = %d, payload = %s", __FUNCTION__, handle, payload.c_str());
|
||||
|
||||
boost::asio::post(context_, [handle, payload = payload, this]() {
|
||||
if (experts_.count(handle) > 0)
|
||||
experts_[handle]->SendResponse(payload);
|
||||
});
|
||||
}
|
||||
|
||||
int MtServiceImpl::GetCommandType(int handle)
|
||||
{
|
||||
log_.Trace("%s: handle = %d", __FUNCTION__, handle);
|
||||
|
||||
std::packaged_task<int()> task([handle, this]() {
|
||||
return (experts_.count(handle) > 0) ? experts_[handle]->GetCommandType() : 0;
|
||||
});
|
||||
auto f = task.get_future();
|
||||
boost::asio::post(context_, std::bind(std::move(task)));
|
||||
return f.get();
|
||||
}
|
||||
|
||||
std::string MtServiceImpl::GetCommandPayload(int handle)
|
||||
{
|
||||
log_.Trace("%s: handle = %d", __FUNCTION__, handle);
|
||||
|
||||
std::packaged_task<std::string()> task([handle, this]() {
|
||||
return (experts_.count(handle) > 0) ? experts_[handle]->GetCommandPayload() : 0;
|
||||
});
|
||||
auto f = task.get_future();
|
||||
boost::asio::post(context_, std::bind(std::move(task)));
|
||||
return f.get();
|
||||
}
|
||||
|
||||
void MtServiceImpl::LogError(const std::string& error)
|
||||
{
|
||||
log_.Error("%s: %s", __FUNCTION__, error.c_str());
|
||||
}
|
||||
|
||||
void MtServiceImpl::OnServerStopped(unsigned short port)
|
||||
{
|
||||
log_.Trace("%s: port = %d", __FUNCTION__, port);
|
||||
|
||||
if (servers_.count(port) > 0)
|
||||
servers_.erase(port);
|
||||
}
|
||||
|
||||
void MtServiceImpl::ThreadProc()
|
||||
{
|
||||
log_.Debug("%s: started", __FUNCTION__);
|
||||
context_.run();
|
||||
log_.Debug("%s: stopped", __FUNCTION__);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
// MtService
|
||||
//--------------------------------------------------------------------------------
|
||||
|
||||
MtService::MtService()
|
||||
{
|
||||
LogConfigurator::Setup(LogLevel::Trace, OutputType::Console | OutputType::File, "MtApiService");
|
||||
impl_ = std::make_unique<MtServiceImpl>();
|
||||
}
|
||||
|
||||
MtService::~MtService()
|
||||
{
|
||||
}
|
||||
|
||||
MtService& MtService::GetInstance()
|
||||
{
|
||||
static MtService instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
void MtService::InitExpert(int port, int handle, std::unique_ptr<MetaTraderHandler> mt_handler)
|
||||
{
|
||||
impl_->InitExpert(port, handle, std::move(mt_handler));
|
||||
}
|
||||
|
||||
void MtService::DeinitExpert(int handle)
|
||||
{
|
||||
impl_->DeinitExpert(handle);
|
||||
}
|
||||
|
||||
void MtService::SendEvent(int handle, int event_type, const std::string& payload)
|
||||
{
|
||||
impl_->SendEvent(handle, event_type, payload);
|
||||
}
|
||||
|
||||
void MtService::SendResponse(int handle, const std::string& payload)
|
||||
{
|
||||
impl_->SendResponse(handle, payload);
|
||||
}
|
||||
|
||||
int MtService::GetCommandType(int handle)
|
||||
{
|
||||
return impl_->GetCommandType(handle);
|
||||
}
|
||||
|
||||
std::string MtService::GetCommandPayload(int handle)
|
||||
{
|
||||
return impl_->GetCommandPayload(handle);
|
||||
}
|
||||
|
||||
void MtService::LogError(const std::string& error)
|
||||
{
|
||||
impl_->LogError(error);
|
||||
}
|
||||
Reference in New Issue
Block a user