diff --git a/src/configs/version.hpp b/src/configs/version.hpp index 18d1017..c681d56 100644 --- a/src/configs/version.hpp +++ b/src/configs/version.hpp @@ -1,2 +1,2 @@ #pragma once -#define VERSION "2.1" \ No newline at end of file +#define VERSION "2.2" \ No newline at end of file diff --git a/src/service/extapi_service.cpp b/src/service/extapi_service.cpp index cc308e2..68f7a21 100644 --- a/src/service/extapi_service.cpp +++ b/src/service/extapi_service.cpp @@ -4,6 +4,7 @@ #include "ixwebsocket/IXWebSocketServer.h" #include "utils/stringutils.hpp" #include "utils/urlparser.hpp" +#include "wbesocket_connect_mgr_service.hpp" // #include "iflytop/components/zcanreceiver/zcanreceiverhost.hpp" // #include "iflytop/core/components/stringutils.hpp" @@ -20,26 +21,6 @@ using namespace ix; namespace iflytop {}; -// static map>> wsClients; - -static void insertNewClient(string chname, shared_ptr client) { - if (client == nullptr) return; - if (chname.empty()) return; - if (wsClients.find(chname) == wsClients.end()) { - wsClients[chname] = list>(); - } - wsClients[chname].push_back(client); -} - -static void removeClient(string chname, shared_ptr client) { - if (wsClients.find(chname) != wsClients.end()) { - wsClients[chname].remove(client); - } -} - -static list> &getWsClients(string chname) { return wsClients[chname]; } - void ExtAPIService::initialize() { toml::table config; @@ -78,7 +59,7 @@ void ExtAPIService::initialize() { if (cmd == "restart") { exit(0); } else if (cmd == "getStatus" || cmd == "get-status") { - receipt["status"] = 0; + receipt["status"] = 0; for (auto it : DataChannelMgr::getChannels()) { if (it->getAlias().empty()) { receipt["data"][it->getChannelName()] = it->getChannelInfo(); @@ -89,6 +70,9 @@ void ExtAPIService::initialize() { } else if (cmd == "getVersion") { receipt["status"] = 0; receipt["data"]["version"] = VERSION; + } else if (cmd == "getConnections") { + receipt["status"] = 0; + receipt["data"] = WbesocketConnectMgrService::getConnectionList(); } } @@ -136,8 +120,7 @@ void ExtAPIService::initialize() { } string chname = webSocket.getUrl().substr(1); - insertNewClient(chname, findws(chname)); - + WbesocketConnectMgrService::insertNewClient(chname, findws(chname), make_shared(connectionState->getRemoteIp())); } else if (msg->type == ix::WebSocketMessageType::Message) { string chname = webSocket.getUrl().substr(1); auto channel = DataChannelMgr::findByChannel(chname); @@ -148,23 +131,17 @@ void ExtAPIService::initialize() { } } else if (msg->type == ix::WebSocketMessageType::Close) { string chname = webSocket.getUrl().substr(1); - removeClient(chname, findws(chname)); + logger->info("close connect ip: {},url: {}, channel:{}", connectionState->getRemoteIp(), webSocket.getUrl(), chname); + WbesocketConnectMgrService::removeClient(chname, findws(chname)); } }); // On Data From Channel DataChannelMgr::regOnChannelData([this](IDataChannel *fromch, bool binary, const char *data, size_t len) { + logger->info("ondata from channel {}", fromch->getChannelName()); list> clients; - auto chs = getWsClients(fromch->getChannelName()); - for (auto it : chs) { - clients.push_back(it); - } - - auto aliaschs = getWsClients(fromch->getAlias()); - for (auto it : aliaschs) { - clients.push_back(it); - } - + WbesocketConnectMgrService::findClientByName(fromch->getChannelName(), clients); + WbesocketConnectMgrService::findClientByName(fromch->getAlias(), clients); for (auto ch : clients) { if (ch) { if (binary) { diff --git a/src/service/wbesocket_connect_mgr_service.cpp b/src/service/wbesocket_connect_mgr_service.cpp new file mode 100644 index 0000000..306fba0 --- /dev/null +++ b/src/service/wbesocket_connect_mgr_service.cpp @@ -0,0 +1,72 @@ +#include "wbesocket_connect_mgr_service.hpp" + +using namespace iflytop; +using namespace core; +using namespace std; +using namespace nlohmann; +using namespace ix; + +// static map>> wsClients; +static map> wsClientsInfo; +static std::mutex wsClientsLock; + +shared_ptr findwsinfo(shared_ptr client) { + if (client == nullptr) return nullptr; + auto it = wsClientsInfo.find((void *)client.get()); + if (it == wsClientsInfo.end()) return nullptr; + return it->second; +} + +void WbesocketConnectMgrService::insertNewClient(string chname, shared_ptr client, shared_ptr connectInfo) { + lock_guard lock(wsClientsLock); + if (client == nullptr) return; + if (chname.empty()) return; + if (wsClients.find(chname) == wsClients.end()) { + wsClients[chname] = list>(); + } + wsClients[chname].push_back(client); + wsClientsInfo[(void *)client.get()] = connectInfo; + GET_LOGGER(WSConnectMgr)->info("new client: {} {}, channel: {}", client->getUrl(), (void *)client.get(), chname); +} +void WbesocketConnectMgrService::removeClient(string chname, shared_ptr client) { + lock_guard lock(wsClientsLock); + if (client == nullptr) { + return; + } + + if (wsClients.find(chname) != wsClients.end()) { + wsClients[chname].remove(client); + wsClientsInfo.erase((void *)client.get()); + GET_LOGGER(WSConnectMgr)->info("remove client: {} {}, channel: {}", client->getUrl(), (void *)client.get(), chname); + } +} +void WbesocketConnectMgrService::findClientByName(string chname, list> &clients) { + lock_guard lock(wsClientsLock); + auto it = wsClients.find(chname); + if (it == wsClients.end()) { + return; + } + + for (auto ch : it->second) { + clients.push_back(ch); + } +} + +json WbesocketConnectMgrService::getConnectionList() { + lock_guard lock(wsClientsLock); + json j; + for (auto it : wsClients) { + json jlist; + jlist["channelName"] = it.first; + for (auto ch : it.second) { + json chj; + chj["uri"] = ch->getUrl(); + chj["ptr"] = (int64_t)(void *)ch.get(); + chj["remoteIp"] = findwsinfo(ch) ? findwsinfo(ch)->getRemoteIp() : "null"; + jlist["connections"].push_back(chj); + } + j.push_back(jlist); + } + return j; +} diff --git a/src/service/wbesocket_connect_mgr_service.hpp b/src/service/wbesocket_connect_mgr_service.hpp new file mode 100644 index 0000000..a6519e5 --- /dev/null +++ b/src/service/wbesocket_connect_mgr_service.hpp @@ -0,0 +1,50 @@ +// +// Created by zwsd +// + +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// +#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 + +namespace iflytop { +using namespace std; +using namespace nlohmann; +using namespace ix; + +class WebSocketConnectInfo { + string remoteIp; + + public: + WebSocketConnectInfo() {} + WebSocketConnectInfo(string ip) : remoteIp(ip) {} + string getRemoteIp() { return remoteIp; } +}; + +class WbesocketConnectMgrService { + public: + static void insertNewClient(string chname, shared_ptr client, shared_ptr connectInfo); + static void removeClient(string chname, shared_ptr client); + static void findClientByName(string chname, list> &clients); + static json getConnectionList(); +}; + +} // namespace iflytop