From 562f24e607c19a47ff915e95ffbe6fbd9cd57e43 Mon Sep 17 00:00:00 2001 From: zhaohe Date: Thu, 27 Mar 2025 11:36:16 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=9E=84=E4=BB=A3=E7=A0=81=EF=BC=8C?= =?UTF-8?q?=E6=8A=BD=E8=B1=A1=E5=87=BAIDataChannel=E5=B1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 1 + libs/README.md | 5 +- src/components/channel/channel_factory.cpp | 22 ++++ src/components/channel/channel_factory.hpp | 24 ++++ src/components/channel/idata_channel.hpp | 44 +++++++ src/components/channel/zcanchannel.cpp | 44 +++++++ src/components/channel/zcanchannel.hpp | 46 +++++++ .../zcanreceiver/socket_can/socket_can.cpp | 9 +- .../zservice_container/zservice_container.hpp | 39 +++--- src/extapi_service.cpp | 102 ---------------- src/extapi_service.hpp | 65 ---------- src/main.cpp | 23 +++- src/main_control_service.cpp | 44 ------- src/main_control_service.hpp | 60 --------- src/service/app_config_service.cpp | 0 src/service/app_config_service.hpp | 30 +++++ src/service/extapi_service.cpp | 135 +++++++++++++++++++++ src/service/extapi_service.hpp | 52 ++++++++ 18 files changed, 443 insertions(+), 302 deletions(-) create mode 100644 src/components/channel/channel_factory.cpp create mode 100644 src/components/channel/channel_factory.hpp create mode 100644 src/components/channel/idata_channel.hpp create mode 100644 src/components/channel/zcanchannel.cpp create mode 100644 src/components/channel/zcanchannel.hpp delete mode 100644 src/extapi_service.cpp delete mode 100644 src/extapi_service.hpp delete mode 100644 src/main_control_service.cpp delete mode 100644 src/main_control_service.hpp create mode 100644 src/service/app_config_service.cpp create mode 100644 src/service/app_config_service.hpp create mode 100644 src/service/extapi_service.cpp create mode 100644 src/service/extapi_service.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 05b5623..e28f17e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -78,6 +78,7 @@ zadd_executable( thirdlib/ libs/libixwebsocket/include # thirdlib/spdlog/include/ # + libs/tomlplusplus/ src ${IFLYTOP_LINK_SDK_INCLUDE_PATH} diff --git a/libs/README.md b/libs/README.md index 7227ec9..42de7d0 100644 --- a/libs/README.md +++ b/libs/README.md @@ -1 +1,4 @@ -相关说明参考: https://iflytop1.feishu.cn/wiki/wikcn6BuFh5CVsWhCiGgW5489Fe \ No newline at end of file +相关说明参考: https://iflytop1.feishu.cn/wiki/wikcn6BuFh5CVsWhCiGgW5489Fe + + libixwebsocket: https://machinezone.github.io/IXWebSocket/usage/ + \ No newline at end of file diff --git a/src/components/channel/channel_factory.cpp b/src/components/channel/channel_factory.cpp new file mode 100644 index 0000000..ce88eb1 --- /dev/null +++ b/src/components/channel/channel_factory.cpp @@ -0,0 +1,22 @@ +#include "channel_factory.hpp" + +using namespace iflytop; +using namespace std; + +static IDataChannel::OnData_t s_ondata; +static map s_channels; + +map ChannelFactory::createChannels(string cfgfile) { + ZCanChannel *canChannel = new ZCanChannel("zcan", "can0", 500000); + canChannel->initialize(); + canChannel->registerOnDataCallback([](IDataChannel *ch, const string &data) { + if (s_ondata) s_ondata(ch, data); + }); + s_channels[canChannel->getChannelName()] = canChannel; + return s_channels; + + // canChannel->initialize(can_if_name, baudrate); + // channels["zcan"] = canChannel; +} + +void ChannelFactory::regOnChannelData(IDataChannel::OnData_t ondata) { s_ondata = ondata; } diff --git a/src/components/channel/channel_factory.hpp b/src/components/channel/channel_factory.hpp new file mode 100644 index 0000000..3e527ab --- /dev/null +++ b/src/components/channel/channel_factory.hpp @@ -0,0 +1,24 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// +#include "idata_channel.hpp" +#include "zcanchannel.hpp" +namespace iflytop { +using namespace std; + +class ChannelFactory { + public: + static map createChannels(string cfgfile); + static void regOnChannelData(IDataChannel::OnData_t ondata); +}; + +} // namespace iflytop \ No newline at end of file diff --git a/src/components/channel/idata_channel.hpp b/src/components/channel/idata_channel.hpp new file mode 100644 index 0000000..e911dfb --- /dev/null +++ b/src/components/channel/idata_channel.hpp @@ -0,0 +1,44 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "thirdlib/nlohmann/json.hpp" +namespace iflytop { +using namespace nlohmann; +using namespace std; + +class IDataChannel { + private: + /* data */ + public: + typedef std::function OnData_t; + + public: + virtual string getChannelName() = 0; + virtual list getCmdList() = 0; + + virtual void senddata(const string& data) = 0; + virtual void registerOnDataCallback(OnData_t ondata) = 0; + virtual void callcmd(string cmd, unordered_map param, json& receipt) = 0; + + virtual ~IDataChannel() {} + + protected: + string paramToString(const unordered_map& param) { + string ret; + for (auto& [key, value] : param) { + ret += key + "=" + value + "&"; + } + return ret; + } +}; + +} // namespace iflytop \ No newline at end of file diff --git a/src/components/channel/zcanchannel.cpp b/src/components/channel/zcanchannel.cpp new file mode 100644 index 0000000..daf97d3 --- /dev/null +++ b/src/components/channel/zcanchannel.cpp @@ -0,0 +1,44 @@ +#include "zcanchannel.hpp" + +#include "utils/stringutils.hpp" +using namespace nlohmann; +using namespace iflytop; + +ZCanChannel::ZCanChannel(string name, string can_if_name, int baudrate) { + m_chname = name; + m_can_if_name = can_if_name; + m_baudrate = baudrate; + logger->info("New ZCanChannel {}, canif:{}, baudrate:{}", m_chname, can_if_name, baudrate); +} + +void ZCanChannel::initialize() { + logger->info("{} initialize", m_chname); + m_zcanreceiverhost.reset(new ZCanReceiverHost()); + m_zcanreceiverhost->initialize(m_can_if_name, m_baudrate); + + m_zcanreceiverhost->registerListener([this](uint8_t fromboardid, uint8_t* packet, size_t len) { + string hexStr = StringUtils().bytesToString((uint8_t*)packet, len); + logger->info("RX:<- {}({})", m_chname, hexStr, len); + if (m_ondata) m_ondata(this, hexStr); + }); +} + +void ZCanChannel::senddata(const string& data) { + logger->info("{} TX:-> {}({})", m_chname, data, data.length()); + vector rxbyte; + StringUtils().hexStringToBytes(data, "", rxbyte); + m_zcanreceiverhost->sendPacket(rxbyte.data(), rxbyte.size()); +} +void ZCanChannel::registerOnDataCallback(OnData_t ondata) { m_ondata = ondata; } +void ZCanChannel::callcmd(string cmd, unordered_map param, json& receipt) { + logger->info("{} callcmd {} {}", m_chname, cmd, paramToString(param)); + if (cmd == "restart") { + m_zcanreceiverhost->restartCanInterface(); + } +} + +list ZCanChannel::getCmdList() { + list cmdlist; + cmdlist.push_back("restart"); + return cmdlist; +} diff --git a/src/components/channel/zcanchannel.hpp b/src/components/channel/zcanchannel.hpp new file mode 100644 index 0000000..be8aca3 --- /dev/null +++ b/src/components/channel/zcanchannel.hpp @@ -0,0 +1,46 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "components/zcanreceiver/zcanreceiverhost.hpp" +#include "components/zservice_container/zservice_container.hpp" +#include "idata_channel.hpp" +namespace iflytop { +using namespace std; +using namespace nlohmann; +using namespace core; + +class ZCanChannel : public IDataChannel { + ENABLE_LOGGER(ZCanChannel); + + private: + /* data */ + + shared_ptr m_zcanreceiverhost; + OnData_t m_ondata; + string m_chname; + string m_can_if_name; + int m_baudrate; + + public: + ZCanChannel(string name, string can_if_name, int baudrate); + + virtual string getChannelName() { return m_chname; } + + void initialize(); + + virtual void senddata(const string& data); + virtual void registerOnDataCallback(OnData_t ondata); + virtual void callcmd(string cmd, unordered_map param, json& receipt); + virtual list getCmdList(); +}; + +} // namespace iflytop \ No newline at end of file diff --git a/src/components/zcanreceiver/socket_can/socket_can.cpp b/src/components/zcanreceiver/socket_can/socket_can.cpp index 8c57b41..02af7af 100644 --- a/src/components/zcanreceiver/socket_can/socket_can.cpp +++ b/src/components/zcanreceiver/socket_can/socket_can.cpp @@ -84,7 +84,6 @@ SocketCan::~SocketCan() { } void SocketCan::setCanBitrate(string canName, int bitrate) { - logger->info("set can:{} bitrate:{}", canName, bitrate); dosystem(fmt::format("ip link set {} down", canName)); dosystem(fmt::format("ip link set {} type can bitrate {}", canName, bitrate)); dosystem(fmt::format("ip link set {} up", canName)); @@ -100,6 +99,7 @@ void SocketCan::startCanInterface() { lock_guard lock(thislock); // 尝试恢复CAN总线 + bool restart = false; if (m_readThread) { logger->warn("try to recover can bus............................................"); m_readThread->join(); @@ -107,6 +107,7 @@ void SocketCan::startCanInterface() { if (m_socketCanFd > 0) close(m_socketCanFd); m_socketCanFd = -1; + restart = true; } socketcanInitialize(); @@ -118,7 +119,7 @@ void SocketCan::startCanInterface() { m_canErrorFlag = false; m_canBusIsReady = true; - logger->warn("start can bus ok............................................"); + if (restart) logger->warn("start can bus ok............................................"); } void SocketCan::socketcanInitialize() { @@ -140,9 +141,7 @@ void SocketCan::socketcanInitialize() { if (m_socketCanFd > 0) close(m_socketCanFd); - logger->info("socketcanInitialize,canName:{},canBaudrate:{}", m_socketCanConfig->m_canName, m_socketCanConfig->m_canBaudrate); - - // 配置socketCan波特率,注意该方法必须放在socket之前 + // 配置socketCan波特率,注意该方法必须放在socket之前 setCanBitrate(m_socketCanConfig->m_canName, m_socketCanConfig->m_canBaudrate); // SOCKET diff --git a/src/components/zservice_container/zservice_container.hpp b/src/components/zservice_container/zservice_container.hpp index 6846ea3..bf741e9 100644 --- a/src/components/zservice_container/zservice_container.hpp +++ b/src/components/zservice_container/zservice_container.hpp @@ -15,7 +15,8 @@ #include #include #include - +// +#include "spdlogfactory/logger_factory.hpp" /** * @brief * @@ -42,8 +43,7 @@ class ZserviceContainerAny { template explicit ZserviceContainerAny(const ValueType& value) : content_(new Holder(value)) {} - ZserviceContainerAny(const ZserviceContainerAny& other) - : content_(other.content_ ? other.content_->clone() : nullptr) {} + ZserviceContainerAny(const ZserviceContainerAny& other) : content_(other.content_ ? other.content_->clone() : nullptr) {} public: ZserviceContainerAny& swap(ZserviceContainerAny& rhs) { @@ -87,7 +87,7 @@ class ZserviceContainerAny { public: virtual const std::type_info& GetType() const = 0; - virtual ZPlaceHolder* clone() const = 0; + virtual ZPlaceHolder* clone() const = 0; }; template @@ -136,7 +136,7 @@ ValueType zany_cast(const ZserviceContainerAny& any) { class ServiceContrainer { map services; - ServiceContrainer(){}; + ServiceContrainer() {}; public: static ServiceContrainer& get(); @@ -148,7 +148,7 @@ class ServiceContrainer { } object->initialize(); type_index index = typeid(T); - services[index] = ZserviceContainerAny(object); + services[index] = ZserviceContainerAny(object); }; template void regService(shared_ptr object) { @@ -156,13 +156,14 @@ class ServiceContrainer { return; } type_index index = typeid(T); - services[index] = ZserviceContainerAny(object); + services[index] = ZserviceContainerAny(object); }; template - shared_ptr getService() { - type_index index = typeid(T); - auto result = services.find(index); + shared_ptr getService(string fromfile, int fromline) { + type_index index = typeid(T); + auto result = services.find(index); if (result == services.end()) { + spdlog::error("[{}:{}]getService({}) fail", fromfile, fromline, index.name()); return nullptr; } return result->second.Get>(); @@ -170,8 +171,8 @@ class ServiceContrainer { template void getToService(shared_ptr& service) { - type_index index = typeid(T); - auto result = services.find(index); + type_index index = typeid(T); + auto result = services.find(index); if (result == services.end()) { service = nullptr; } @@ -179,25 +180,19 @@ class ServiceContrainer { }; }; -#define GET_SERVICE(type) (ServiceContrainer::get().getService()) -#define GET_TO_SERVICE(value) \ - ServiceContrainer::get().getToService(value); \ - if (value == nullptr) { \ - logger->error("[{}:{}]GET_TO_SERVICE({}) fail", __FILE__, __LINE__, #value); \ - exit(-1); \ - }; +#define GET_SERVICE(type) (ServiceContrainer::get().getService(__FILE__, __LINE__)) #define BUILD_AND_REG_SERRVICE(type, ...) \ - logger->info("build {}.....", #type); \ + spdlog::info("build {}.....", #type); \ shared_ptr type##_val(new type(__VA_ARGS__)); \ ServiceContrainer::get().regService(type##_val); -#define REG_SERRVICE(type,object) \ +#define REG_SERRVICE(type, object) \ shared_ptr type##_val(object); \ ServiceContrainer::get().regService(type##_val); #define BUILD_AND_REG_MOCK_SERRVICE(type, mocktype, ...) \ - logger->info("build {}.....", #type); \ + spdlog::info("build {}.....", #type); \ shared_ptr type##_val(new mocktype(__VA_ARGS__)); \ ServiceContrainer::get().regService(type##_val); diff --git a/src/extapi_service.cpp b/src/extapi_service.cpp deleted file mode 100644 index 0ba3a4b..0000000 --- a/src/extapi_service.cpp +++ /dev/null @@ -1,102 +0,0 @@ -#include "extapi_service.hpp" - -#include "configs/project_setting.hpp" -#include "configs/version.hpp" -#include "ixwebsocket/IXWebSocketServer.h" -#include "utils/stringutils.hpp" -#include "utils/urlparser.hpp" - -// #include "iflytop/components/zcanreceiver/zcanreceiverhost.hpp" -// #include "iflytop/core/components/stringutils.hpp" -// #include "iflytop/core/core.hpp" - -using namespace iflytop; -using namespace core; -using namespace std; -using namespace nlohmann; -using namespace ix; - -#define BIND -namespace iflytop {}; -void ExtAPIService::initialize(string can_if_name, int baudrate) { - GET_TO_SERVICE(m_zconfig); - - m_zcanreceiverhost.reset(new ZCanReceiverHost()); - m_zcanreceiverhost->initialize(can_if_name, baudrate); - - initCanPassthroughServer(); -}; -void ExtAPIService::processRXData(weak_ptr webSocket, const ix::WebSocketMessagePtr &msg) {} - -void ExtAPIService::initCanPassthroughServer() { - m_httpServer.reset(new HttpServer(19004, "0.0.0.0")); - m_httpServer->listen(); - m_httpServer->start(); - m_httpServer->setOnConnectionCallback( // - [this](HttpRequestPtr request, std::shared_ptr connectionState) -> HttpResponsePtr { - HTTP_URL httpurl = URLParser::Parse(request->uri); - - if (httpurl.getPath() == "/restartCanif") { - logger->info("call {}", request->uri); - m_zcanreceiverhost->restartCanInterface(); - } else if (httpurl.getPath() == "/killself") { - logger->info("call {}", request->uri); - exit(1); - } else { - logger->warn("call unknown {}", httpurl.getPath()); - } - - return std::make_shared(200, "", HttpErrorCode::Ok, WebSocketHttpHeaders(), ""); - }); - - /** - * - * protocol: websocket - * port : 19005 - * descript: 直接透传CAN数据,不做任何处理 - * - */ - m_canPassthroughServer.reset(new WebSocketServer(19005, "0.0.0.0")); - m_canPassthroughServer->setOnConnectionCallback([this](weak_ptr webSocket, shared_ptr connectionState) { - logger->info("url: {}", webSocket.lock()->getUrl()); - - logger->info("m_canPassthroughServer on connect remote ip: {}", connectionState->getRemoteIp()); - auto ws = webSocket.lock(); - if (!ws) return; - - ws->setOnMessageCallback([this, webSocket](const ix::WebSocketMessagePtr &msg) { // - logger->info("m_canPassthroughServer on message {}", webSocket.lock()->getUrl()); - try { - if (msg->type == ix::WebSocketMessageType::Message) { - logger->info("websocket-ch -> {}({})", msg->str, msg->wireSize); - string hexStr = msg->str; - vector rxbyte; - StringUtils().hexStringToBytes(hexStr, "", rxbyte); - m_zcanreceiverhost->sendPacket(rxbyte.data(), rxbyte.size()); - } else if (msg->type == ix::WebSocketMessageType::Open) { - logger->info("websocket-ch on open"); - } - } catch (const std::exception &e) { - logger->error("catch error: {}", e.what()); - } - }); - }); - - m_canPassthroughServer->setOnClientMessageCallback([this](std::shared_ptr, WebSocket &, const WebSocketMessagePtr &) { - - - - }); - - m_zcanreceiverhost->registerListener([this](uint8_t fromboardid, uint8_t *packet, size_t len) { - string hexStr = StringUtils().bytesToString((uint8_t *)packet, len); - auto clients = m_canPassthroughServer->getClients(); - logger->info("websocket-ch <- {}({})", hexStr, len); - - for (auto &each : clients) { - if (each) each->sendText(hexStr); - } - }); - - m_canPassthroughServer->listenAndStart(); -} diff --git a/src/extapi_service.hpp b/src/extapi_service.hpp deleted file mode 100644 index 4cc3f3c..0000000 --- a/src/extapi_service.hpp +++ /dev/null @@ -1,65 +0,0 @@ -// -// Created by zwsd -// - -#pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// #include "iflytop/components/iflytop_front_end_service/iflytop_front_end_service.hpp" -// #include "iflytop/components/restful_server/restful_server.hpp" -// #include "iflytop/core/components/jobs/work_queue.hpp" -// #include "iflytop/core/components/timer/simple_timer.hpp" -// #include "iflytop/core/spdlogfactory/logger.hpp" -// #include "iflytop/components/iflytop_front_end_service/iflytop_front_end_service.hpp" -// #include "iflytoplinuxsdk/src/iflytop/core/components/zservice_container/zservice_container.hpp" - -// -#include "components/zcanreceiver/zcanreceiverhost.hpp" -#include "components/zservice_container/zservice_container.hpp" -#include "configs/gconfig.hpp" -#include "ixwebsocket/IXHttp.h" -#include "ixwebsocket/IXHttpServer.h" -#include "ixwebsocket/IXWebSocketServer.h" -#include "spdlogfactory/logger.hpp" -// - -// -#include - -/** - * @brief - * - * service: 对外暴露的接口服务 - * - */ - -namespace iflytop { -using namespace std; -using namespace core; -using namespace ix; - -class ExtAPIService { - ENABLE_LOGGER(ExtAPIService); - - shared_ptr m_zconfig; - shared_ptr m_canPassthroughServer; // 19005 - shared_ptr m_httpServer;//19004 - shared_ptr m_zcanreceiverhost; - - public: - ExtAPIService() {}; - void initialize(string can_if_name, int baudrate); - - private: - void initCanPassthroughServer(); - void processRXData(weak_ptr webSocket, const ix::WebSocketMessagePtr &msg); -}; -} // namespace iflytop \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index d168b28..430a4cc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,7 +2,15 @@ #include #include -#include "main_control_service.hpp" +// +#include "configs/project_setting.hpp" +#include "configs/version.hpp" +#include "utils/stringutils.hpp" +// +// +#include "service/extapi_service.hpp" +// +#include "service/app_config_service.hpp" using namespace iflytop; using namespace core; @@ -12,8 +20,17 @@ using namespace std; * MAIN => MAIN * *******************************************************************************/ int main(int argc, char *argv[]) { - shared_ptr main = make_shared(); - main->initialize(argc, argv); + spdlog::info("system setup start."); + spdlog::flush_on(spdlog::level::debug); + spdlog::info("#"); + spdlog::info("# company:{}", "ifytop"); + spdlog::info("# version:{}", VERSION); + spdlog::info("#"); + spdlog::info("build {}.....", "Config"); + + BUILD_AND_REG_SERRVICE(ExtAPIService); + GET_SERVICE(ExtAPIService)->initialize(); + while (true) { sleep(1); } diff --git a/src/main_control_service.cpp b/src/main_control_service.cpp deleted file mode 100644 index f67a768..0000000 --- a/src/main_control_service.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include "main_control_service.hpp" - -#include "configs/project_setting.hpp" -#include "configs/version.hpp" -#include "utils/stringutils.hpp" -// -#include "components/zservice_container/zservice_container.hpp" -// - -using namespace iflytop; -using namespace core; -using namespace std; -using namespace nlohmann; - -#define OBJECT GET_SERVICE - -namespace iflytop {}; -void MainControlService::initialize(int argc, char *argv[]) { - /** - * @brief 系统初始化 - */ - logger->info("system setup start."); - spdlog::flush_on(spdlog::level::debug); - logger->info("#"); - logger->info("# company:{}", "ifytop"); - logger->info("# version:{}", VERSION); - logger->info("#"); - logger->info("build {}.....", "Config"); - - initializeService(); -}; - -void MainControlService::initializeService() { - BUILD_AND_REG_SERRVICE(GConfig); - OBJECT(GConfig)->initialize(); - - m_extAPIService.initialize(OBJECT(GConfig)->get_canName(), OBJECT(GConfig)->get_canBaudRate()); - - - // ZCanReceiverHost *m_zcanreceiverhost = new ZCanReceiverHost(); - // m_zcanreceiverhost->initialize(OBJECT(GConfig)->get_canName(), OBJECT(GConfig)->get_canBaudRate()); - // m_zcanreceiverhost->sendPacket((uint8_t *)"hello", 5); - -} diff --git a/src/main_control_service.hpp b/src/main_control_service.hpp deleted file mode 100644 index 8fde3e1..0000000 --- a/src/main_control_service.hpp +++ /dev/null @@ -1,60 +0,0 @@ -// -// Created by zwsd -// - -#pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// #include "iflytop/components/restful_server/restful_server.hpp" -// #include "iflytop/core/components/jobs/work_queue.hpp" -// #include "iflytop/core/components/timer/simple_timer.hpp" -// #include "iflytop/core/spdlogfactory/logger.hpp" -// #include "iflytoplinuxsdk/src/iflytop/components/iflytop_front_end_service/iflytop_front_end_service.hpp" -// #include "configs/gconfig.hpp" -// #include "iflytop/components/iflytop_front_end_service/iflytop_front_end_service.hpp" -// #include "iflytoplinuxsdk/src/iflytop/core/components/zservice_container/zservice_container.hpp" -// - -#include "extapi_service.hpp" -#include "spdlogfactory/logger.hpp" -// - -// -// #include "extapi_service.hpp" - -/** - * @brief - * - * service: MainControlService - * - * 监听事件: - * 依赖状态: - * 依赖服务: - * 作用: - * - */ - -namespace iflytop { -using namespace std; -using namespace core; -class MainControlService : public enable_shared_from_this { - ENABLE_LOGGER(MainControlService); - - ExtAPIService m_extAPIService; - - public: - MainControlService() {}; - void initialize(int argc, char *argv[]); - - private: - void initializeService(); -}; -} // namespace iflytop \ No newline at end of file diff --git a/src/service/app_config_service.cpp b/src/service/app_config_service.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/service/app_config_service.hpp b/src/service/app_config_service.hpp new file mode 100644 index 0000000..ce2b25e --- /dev/null +++ b/src/service/app_config_service.hpp @@ -0,0 +1,30 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// +#include "spdlogfactory/logger.hpp" + +namespace iflytop { +using namespace std; +using namespace core; + +class AppConfigService { + ENABLE_LOGGER(AppConfigService); + + private: + /* data */ + public: + void initialize(); +}; + +} // namespace iflytop \ No newline at end of file diff --git a/src/service/extapi_service.cpp b/src/service/extapi_service.cpp new file mode 100644 index 0000000..265a57f --- /dev/null +++ b/src/service/extapi_service.cpp @@ -0,0 +1,135 @@ +#include "extapi_service.hpp" + +#include "configs/project_setting.hpp" +#include "configs/version.hpp" +#include "ixwebsocket/IXWebSocketServer.h" +#include "utils/stringutils.hpp" +#include "utils/urlparser.hpp" + +// #include "iflytop/components/zcanreceiver/zcanreceiverhost.hpp" +// #include "iflytop/core/components/stringutils.hpp" +// #include "iflytop/core/core.hpp" +#include "components/channel/channel_factory.hpp" + +using namespace iflytop; +using namespace core; +using namespace std; +using namespace nlohmann; +using namespace ix; + +namespace iflytop {}; + +static map channels; +// static mapinfo("New HttpServer listen on 19004"); + m_httpServer.reset(new HttpServer(19004, "0.0.0.0")); + m_httpServer->setOnConnectionCallback( // + [this](HttpRequestPtr request, std::shared_ptr connectionState) -> HttpResponsePtr { + HTTP_URL httpurl = URLParser::Parse(request->uri); + + json receipt; + receipt["status"] = 0; + receipt["msg"] = "success"; + + // path: /cmd/???? + if (httpurl.path.size() == 3 && httpurl.path[0] == "cmd") { + string channelName = httpurl.path[1]; + string cmd = httpurl.path[2]; + auto params = httpurl.query; + + // path: /cmd/server/restart + if (channelName == "server" && cmd == "restart") { + exit(0); + } + // path: /cmd/channelName/xxxxxx + else { + auto channel = findChannel(channelName); + if (channel) { + channel->callcmd(cmd, params, receipt); + } else { + receipt["status"] = 1; + receipt["msg"] = "channel not found"; + } + } + } + + return std::make_shared(200, "", HttpErrorCode::Ok, WebSocketHttpHeaders(), receipt.dump(0)); + }); + + if (!m_httpServer->listen().first) { + logger->error("HttpServer listen failed"); + exit(1); + } + m_httpServer->start(); + + /** + * + * protocol: websocket + * port : 19005 + * descript: 直接透传CAN数据,不做任何处理 + * + */ + logger->info("New webSocketServer listen on 19005"); + m_wsServer.reset(new WebSocketServer(19005, "0.0.0.0")); + m_wsServer->setOnClientMessageCallback( + [this](std::shared_ptr connectionState, ix::WebSocket &webSocket, const ix::WebSocketMessagePtr &msg) { + if (msg->type == ix::WebSocketMessageType::Open) { + logger->info("new connect ip: {}", connectionState->getRemoteIp()); + + // path: /channelName + logger->info(" uri: {}", msg->openInfo.uri); + webSocket.setUrl(msg->openInfo.uri); + + logger->info(" headers:"); + for (auto it : msg->openInfo.headers) { + logger->info("\t{}: {}", it.first, it.second); + } + } else if (msg->type == ix::WebSocketMessageType::Message) { + string chname = webSocket.getUrl().substr(1); + auto channel = findChannel(chname); + if (channel) { + channel->senddata(msg->str); + } else { + logger->error("channel not found: {}", chname); + } + } + }); + + // On Data From Channel + ChannelFactory::regOnChannelData([this](IDataChannel *channel, string data) { + auto clients = m_wsServer->getClients(); + for (auto it : clients) { + string chname = it->getUrl().substr(1); + IDataChannel *bindchannel = findChannel(chname); + if (bindchannel == channel) { + it->sendText(data); + } + } + }); + + if (!m_wsServer->listenAndStart()) { + logger->error("WebSocketServer listenAndStart failed"); + exit(1); + } + + // + logger->info("Support Channel List"); + for (auto it : channels) { + logger->info("\t{}", it.second->getChannelName()); + logger->info("\t ws://0.0.0.0:19905/{}", it.second->getChannelName()); + for (auto cmd : it.second->getCmdList()) { + logger->info("\t http:/0.0.0.0:19004/cmd/{}/{}", it.second->getChannelName(), cmd); + } + } +}; diff --git a/src/service/extapi_service.hpp b/src/service/extapi_service.hpp new file mode 100644 index 0000000..bff2d87 --- /dev/null +++ b/src/service/extapi_service.hpp @@ -0,0 +1,52 @@ +// +// Created by zwsd +// + +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// +#include "components/channel/channel_factory.hpp" +#include "components/zcanreceiver/zcanreceiverhost.hpp" +#include "components/zservice_container/zservice_container.hpp" +// +#include "ixwebsocket/IXHttp.h" +#include "ixwebsocket/IXHttpServer.h" +#include "ixwebsocket/IXWebSocketServer.h" +#include "spdlogfactory/logger.hpp" +// +// +#include + +/** + * @brief + * + * service: 对外暴露的接口服务 + * + */ + +namespace iflytop { +using namespace std; +using namespace core; +using namespace ix; + +class ExtAPIService { + ENABLE_LOGGER(ExtAPIService); + + shared_ptr m_wsServer; // 19005 + shared_ptr m_httpServer; // 19004 + + public: + ExtAPIService() {}; + void initialize(); + +}; +} // namespace iflytop \ No newline at end of file