From 8796dacf934b5377f4f747d7cc16fed4b44d4030 Mon Sep 17 00:00:00 2001 From: "Oleg.Korshul" Date: Tue, 6 Dec 2022 16:33:47 +0300 Subject: [PATCH] Add socketio worked version --- Common/3dParty/ixwebsocket/ixwebsocket.pri | 24 +- Common/Network/WebSocket/include/websocket.h | 3 +- .../src/ixwebsocket/ixwebsocket_internal.cpp | 2 +- .../src/ixwebsocket/ixwebsocket_internal.h | 2 +- .../WebSocket/src/managerWebSocket.cpp | 11 + .../src/socketio/socketio_internal.cpp | 220 ++++++++++++++++++ .../src/socketio/socketio_internal.h | 62 +++++ .../src/socketrocket/socketRocket_internal.h | 4 +- .../src/socketrocket/socketRocket_internal.mm | 4 +- Common/Network/WebSocket/src/websocketbase.h | 2 +- Common/Network/WebSocket/websocket.pri | 54 ++++- 11 files changed, 359 insertions(+), 29 deletions(-) create mode 100644 Common/Network/WebSocket/src/socketio/socketio_internal.cpp create mode 100644 Common/Network/WebSocket/src/socketio/socketio_internal.h diff --git a/Common/3dParty/ixwebsocket/ixwebsocket.pri b/Common/3dParty/ixwebsocket/ixwebsocket.pri index f4657c7656..1d5b2f1882 100644 --- a/Common/3dParty/ixwebsocket/ixwebsocket.pri +++ b/Common/3dParty/ixwebsocket/ixwebsocket.pri @@ -1,22 +1,18 @@ -OPENSSL_LIBS_DIRECTORY = $$PWD/../openssl/build/$$CORE_BUILDS_PLATFORM_PREFIX/lib - core_android { ABI_PATH = $$replace(CORE_BUILDS_PLATFORM_PREFIX, "android_", "") contains(ABI_PATH, "armv7" ) { - ABI_PATH = $$replace(ABI_PATH, "armv7", "armeabi-v7a") - } - contains(ABI_PATH, "arm64_v8a" ) { - ABI_PATH = $$replace(ABI_PATH, "arm64_v8a", "arm64-v8a") - } + ABI_PATH = $$replace(ABI_PATH, "armv7", "armeabi-v7a") + } + contains(ABI_PATH, "arm64_v8a" ) { + ABI_PATH = $$replace(ABI_PATH, "arm64_v8a", "arm64-v8a") + } INSTALL_FOLDER = $$PWD/IXWebSocket/build/android/$$ABI_PATH exists($$INSTALL_FOLDER/usr):INSTALL_FOLDER=$$INSTALL_FOLDER/usr INCLUDEPATH += $$INSTALL_FOLDER/include LIBS += $$INSTALL_FOLDER/lib/libixwebsocket.a - - OPENSSL_LIBS_DIRECTORY = $$PWD/../openssl/build/android/$$ABI_PATH/lib } core_ios { @@ -24,8 +20,6 @@ core_ios { INCLUDEPATH += $$PWD/IXWebSocket/build/ios/ixwebsocket-universal/include LIBS += $$PWD/IXWebSocket/build/ios/ixwebsocket-universal/lib/libixwebsocket.a - OPENSSL_LIBS_DIRECTORY = $$PWD/../openssl/build/ios/openssl-universal/lib - } core_linux { @@ -57,11 +51,3 @@ core_windows { LIBS += -lshlwapi } - -core_windows { - LIBS += $$OPENSSL_LIBS_DIRECTORY/libssl.lib - LIBS += $$OPENSSL_LIBS_DIRECTORY/libcrypto.lib -} else { - LIBS += $$OPENSSL_LIBS_DIRECTORY/libssl.a - LIBS += $$OPENSSL_LIBS_DIRECTORY/libcrypto.a -} diff --git a/Common/Network/WebSocket/include/websocket.h b/Common/Network/WebSocket/include/websocket.h index df2be2562b..d33edf6bf3 100644 --- a/Common/Network/WebSocket/include/websocket.h +++ b/Common/Network/WebSocket/include/websocket.h @@ -36,6 +36,7 @@ #include "../../../kernel_config.h" #include #include +#include namespace NSNetwork { @@ -44,7 +45,7 @@ namespace NSNetwork class IWebSocket { public: - virtual void open() = 0; + virtual void open(const std::map& query) = 0; virtual void send(const std::string& message) = 0; virtual void close() = 0; virtual void setUrl(const std::string& url) = 0; diff --git a/Common/Network/WebSocket/src/ixwebsocket/ixwebsocket_internal.cpp b/Common/Network/WebSocket/src/ixwebsocket/ixwebsocket_internal.cpp index 93fac42613..f802ef7cc7 100644 --- a/Common/Network/WebSocket/src/ixwebsocket/ixwebsocket_internal.cpp +++ b/Common/Network/WebSocket/src/ixwebsocket/ixwebsocket_internal.cpp @@ -36,7 +36,7 @@ namespace NSNetwork { namespace NSWebSocket { - void CIXWebSocket::open() + void CIXWebSocket::open(const std::map& query) { ix::SocketTLSOptions tls; tls.caFile = "NONE"; diff --git a/Common/Network/WebSocket/src/ixwebsocket/ixwebsocket_internal.h b/Common/Network/WebSocket/src/ixwebsocket/ixwebsocket_internal.h index 32133fdd96..fcf312b457 100644 --- a/Common/Network/WebSocket/src/ixwebsocket/ixwebsocket_internal.h +++ b/Common/Network/WebSocket/src/ixwebsocket/ixwebsocket_internal.h @@ -55,7 +55,7 @@ namespace NSNetwork public: - virtual void open() override; + virtual void open(const std::map& query) override; virtual void send(const std::string& message) override; virtual void close() override; void receive(const ix::WebSocketMessagePtr& msg); diff --git a/Common/Network/WebSocket/src/managerWebSocket.cpp b/Common/Network/WebSocket/src/managerWebSocket.cpp index 1cb7ced998..d1a1e0994f 100644 --- a/Common/Network/WebSocket/src/managerWebSocket.cpp +++ b/Common/Network/WebSocket/src/managerWebSocket.cpp @@ -40,6 +40,10 @@ #include "./socketrocket/socketRocket_internal.h" #endif +#ifdef USE_IOWEBSOCKET +#include "./socketio/socketio_internal.h" +#endif + namespace NSNetwork { namespace NSWebSocket @@ -65,6 +69,13 @@ namespace NSNetwork return std::make_shared(url, listener); } #endif +#ifdef USE_IOWEBSOCKET + if (sType == "socketio") + { + return std::make_shared(url, listener); + } +#endif + return nullptr; } } diff --git a/Common/Network/WebSocket/src/socketio/socketio_internal.cpp b/Common/Network/WebSocket/src/socketio/socketio_internal.cpp new file mode 100644 index 0000000000..829b2f36ca --- /dev/null +++ b/Common/Network/WebSocket/src/socketio/socketio_internal.cpp @@ -0,0 +1,220 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2021 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#include "socketio_internal.h" +#include +#include "../../../../3dParty/socketio/socket.io-client-cpp/src/internal/sio_packet.h" +#include "../../../../3dParty/socketio/socket.io-client-cpp/src/sio_client.h" +#include "../../../../../../DesktopEditor/graphics/TemporaryCS.h" + +namespace NSNetwork +{ + namespace NSWebSocket + { + class CIOWebSocket_private + { + public: + sio::client m_socket; + NSCriticalSection::CRITICAL_SECTION m_oCS; + CIOWebSocket* m_base; + + public: + CIOWebSocket_private(CIOWebSocket* base) + { + m_base = base; + m_oCS.InitializeCriticalSection(); + } + ~CIOWebSocket_private() + { + m_socket.close(); + m_oCS.DeleteCriticalSection(); + } + + public: + void event_onConnected() + { + m_base->listener->onOpen(); + } + void event_onClose(sio::client::close_reason const& reason) + { + m_base->listener->onClose(0, ""); + } + void event_onFail() + { + m_base->listener->onError(""); + } + + public: + void open(const std::map& query) + { + m_socket.set_open_listener (std::bind(&CIOWebSocket_private::event_onConnected, this)); + m_socket.set_close_listener(std::bind(&CIOWebSocket_private::event_onClose, this, std::placeholders::_1)); + m_socket.set_fail_listener (std::bind(&CIOWebSocket_private::event_onFail, this)); + + sio::message::ptr objAuth = sio::object_message::create(); + //std::string sAuth; + + std::map queryDst = query; + std::map::iterator iterAuth = queryDst.find("token"); + if (iterAuth != queryDst.end()) + { + objAuth->get_map()["token"] = sio::string_message::create(iterAuth->second); + //sAuth = "{\"token\":\"" + iterAuth->second + "\"}"; + queryDst.erase(iterAuth); + } + + //webSocket.connect(url, queryDst, sio::string_message::create(sAuth)); + m_socket.connect(m_base->url, queryDst, objAuth); + + m_socket.socket()->on("message", [&](sio::event& event){ + CTemporaryCS oCS(&m_oCS); + const sio::message::ptr& message = event.get_message(); + if (!message) + return; + + // TODO: пока только текстовые и json команды + switch (message->get_flag()) + { + case sio::message::flag_null: + { + m_base->listener->onMessage("null"); + break; + } + case sio::message::flag_integer: + case sio::message::flag_double: + case sio::message::flag_boolean: + { + m_base->listener->onMessage(""); + break; + } + case sio::message::flag_binary: + { + m_base->listener->onMessage(""); + break; + } + case sio::message::flag_array: + { + m_base->listener->onMessage(""); + break; + } + case sio::message::flag_object: + { + sio::packet_manager manager; + + std::stringstream ss; + sio::packet packet("/", message); + manager.encode( packet, [&](bool isBinary, std::shared_ptr const& json) + { + ss << *json; + }); + manager.reset(); + + std::string result = ss.str(); + + std::size_t indexList = result.find('['); + std::size_t indexObject = result.find('{'); + std::size_t indexString = result.find('"'); + + std::size_t index = indexList; + if (indexObject != std::string::npos && indexObject < index) + index = indexObject; + if (indexString != std::string::npos && indexString < index) + index = indexString; + + if (index != std::string::npos) + result = result.substr(index); + else + result = ""; + + m_base->listener->onMessage(result); + break; + } + case sio::message::flag_string: + { + m_base->listener->onMessage(message->get_string()); + break; + } + default: + break; + } + }); + } + }; + + CIOWebSocket::CIOWebSocket(const std::string& url, std::shared_ptr listener): CWebWorkerBase(url, listener) + { + m_internal = new CIOWebSocket_private(this); + } + + void CIOWebSocket::open(const std::map& query) + { + m_internal->open(query); + } + + void CIOWebSocket::send(const std::string& message_str) + { + //CTemporaryCS (&m_internal->m_oCS); + + // если json -то надо объект + if (0 == message_str.find("{")) + { + sio::packet_manager manager; + sio::message::ptr message; + manager.set_decode_callback([&](sio::packet const& p) + { + message = p.get_message(); + }); + + // Magic message type / ID + manager.put_payload("42" + message_str); + manager.reset(); + + m_internal->m_socket.socket()->emit("message", message); + } + else + { + m_internal->m_socket.socket()->emit("message", sio::string_message::create(message_str)); + } + } + + void CIOWebSocket::close() + { + CTemporaryCS (&m_internal->m_oCS); + m_internal->m_socket.close(); + } + + CIOWebSocket::~CIOWebSocket() + { + delete m_internal; + } + } +} diff --git a/Common/Network/WebSocket/src/socketio/socketio_internal.h b/Common/Network/WebSocket/src/socketio/socketio_internal.h new file mode 100644 index 0000000000..3c4e7bc9f9 --- /dev/null +++ b/Common/Network/WebSocket/src/socketio/socketio_internal.h @@ -0,0 +1,62 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2021 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#ifndef _IO_WEB_SOCKET_H_ +#define _IO_WEB_SOCKET_H_ + +#include "../websocketbase.h" + +namespace NSNetwork +{ + namespace NSWebSocket + { + class CIOWebSocket_private; + class CIOWebSocket: public CWebWorkerBase + { + private: + CIOWebSocket_private* m_internal; + + public: + CIOWebSocket(const std::string& url, std::shared_ptr listener); + virtual ~CIOWebSocket(); + + public: + virtual void open(const std::map& query) override; + virtual void send(const std::string& message) override; + virtual void close() override; + + friend class CIOWebSocket_private; + }; + } +} + +#endif /* _IO_WEB_SOCKET_H_ */ diff --git a/Common/Network/WebSocket/src/socketrocket/socketRocket_internal.h b/Common/Network/WebSocket/src/socketrocket/socketRocket_internal.h index 374a6beae0..5bccbb41bf 100644 --- a/Common/Network/WebSocket/src/socketrocket/socketRocket_internal.h +++ b/Common/Network/WebSocket/src/socketrocket/socketRocket_internal.h @@ -51,7 +51,7 @@ namespace NSNetwork CSocketRocket(const std::string& url, std::shared_ptr listener); ~CSocketRocket(); - virtual void open() override; + virtual void open(const std::map& query) override; virtual void send(const std::string& message) override; virtual void close() override; virtual void setUrl(const std::string& url) override; @@ -60,4 +60,4 @@ namespace NSNetwork } } -#endif /* _SOCKET_ROCKET_H_ */ \ No newline at end of file +#endif /* _SOCKET_ROCKET_H_ */ diff --git a/Common/Network/WebSocket/src/socketrocket/socketRocket_internal.mm b/Common/Network/WebSocket/src/socketrocket/socketRocket_internal.mm index 55f2c057a8..e49f0839d6 100644 --- a/Common/Network/WebSocket/src/socketrocket/socketRocket_internal.mm +++ b/Common/Network/WebSocket/src/socketrocket/socketRocket_internal.mm @@ -60,7 +60,7 @@ namespace NSNetwork delete impl; } - void CSocketRocket::open() + void CSocketRocket::open(const std::map& query) { [impl->wrapped open]; } @@ -81,4 +81,4 @@ namespace NSNetwork } } -} \ No newline at end of file +} diff --git a/Common/Network/WebSocket/src/websocketbase.h b/Common/Network/WebSocket/src/websocketbase.h index 24fa5a8a03..a490ab7fc9 100644 --- a/Common/Network/WebSocket/src/websocketbase.h +++ b/Common/Network/WebSocket/src/websocketbase.h @@ -52,7 +52,7 @@ namespace NSNetwork this->listener = listener; } virtual ~CWebWorkerBase() { close(); } - virtual void open() override {} + virtual void open(const std::map& query) override {} virtual void send(const std::string& message) override {} virtual void close() override {} virtual void setUrl(const std::string& url) override {this->url = url;} diff --git a/Common/Network/WebSocket/websocket.pri b/Common/Network/WebSocket/websocket.pri index d09e91e8d3..ab15dbc670 100644 --- a/Common/Network/WebSocket/websocket.pri +++ b/Common/Network/WebSocket/websocket.pri @@ -2,9 +2,59 @@ core_mac:CONFIG += apple_platform core_ios:CONFIG += apple_platform apple_platform { - CONFIG += socketrocket + CONFIG += socketrocket } else { - CONFIG += ixwebsocket + CONFIG += ixwebsocket +} + +CONFIG += libsocketio + +libsocketio:CONFIG += use_openssl +ixwebsocket:CONFIG += use_openssl + +use_openssl { + include($$PWD/../../3dParty/ixwebsocket/openssl.pri) +} + +libsocketio { + SOCKET_IO_LIB=$$PWD/../../3dParty/socketio/socket.io-client-cpp + + INCLUDEPATH += \ + $$SOCKET_IO_LIB/lib/websocketpp \ + $$SOCKET_IO_LIB/lib/rapidjson/include \ + $$SOCKET_IO_LIB/lib/asio/asio/include + + HEADERS += \ + $$SOCKET_IO_LIB/src/internal/sio_client_impl.h \ + $$SOCKET_IO_LIB/src/internal/sio_packet.h \ + $$SOCKET_IO_LIB/src/sio_message.h \ + $$SOCKET_IO_LIB/src/sio_socket.h \ + $$SOCKET_IO_LIB/src/sio_client.h + + SOURCES += \ + $$SOCKET_IO_LIB/src/internal/sio_client_impl.cpp \ + $$SOCKET_IO_LIB/src/internal/sio_packet.cpp \ + $$SOCKET_IO_LIB/src/sio_socket.cpp \ + $$SOCKET_IO_LIB/src/sio_client.cpp + + DEFINES += \ + BOOST_DATE_TIME_NO_LIB \ + BOOST_REGEX_NO_LIB \ + ASIO_STANDALONE \ + \ + _WEBSOCKETPP_CPP11_STL_ \ + _WEBSOCKETPP_CPP11_FUNCTIONAL_ \ + _WEBSOCKETPP_CPP11_TYPE_TRAITS_ \ + _WEBSOCKETPP_CPP11_CHRONO_ \ + \ + "SIO_TLS=1" + + include($$PWD/../../3dParty/boost/boost.pri) + + DEFINES += USE_IOWEBSOCKET + + HEADERS += $$PWD/src/socketio/socketio_internal.h + SOURCES += $$PWD/src/socketio/socketio_internal.cpp } HEADERS += \