1e509ee18Sopenharmony_ci/* 2e509ee18Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd. 3e509ee18Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4e509ee18Sopenharmony_ci * you may not use this file except in compliance with the License. 5e509ee18Sopenharmony_ci * You may obtain a copy of the License at 6e509ee18Sopenharmony_ci * 7e509ee18Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8e509ee18Sopenharmony_ci * 9e509ee18Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10e509ee18Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11e509ee18Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12e509ee18Sopenharmony_ci * See the License for the specific language governing permissions and 13e509ee18Sopenharmony_ci * limitations under the License. 14e509ee18Sopenharmony_ci */ 15e509ee18Sopenharmony_ci 16e509ee18Sopenharmony_ci#include "ws_server.h" 17e509ee18Sopenharmony_ci 18e509ee18Sopenharmony_ci#include <fstream> 19e509ee18Sopenharmony_ci#include <iostream> 20e509ee18Sopenharmony_ci#include <shared_mutex> 21e509ee18Sopenharmony_ci#include <sys/types.h> 22e509ee18Sopenharmony_ci#include <unistd.h> 23e509ee18Sopenharmony_ci 24e509ee18Sopenharmony_ci#include "common/log_wrapper.h" 25e509ee18Sopenharmony_ci#include "websocket/server/websocket_server.h" 26e509ee18Sopenharmony_ci 27e509ee18Sopenharmony_cinamespace OHOS::ArkCompiler::Toolchain { 28e509ee18Sopenharmony_cistd::shared_mutex g_mutex; 29e509ee18Sopenharmony_ci 30e509ee18Sopenharmony_ci// defined in .cpp file for WebSocketServer forward declaration 31e509ee18Sopenharmony_ciWsServer::WsServer(const DebugInfo& debugInfo, const std::function<void(std::string&&)>& onMessage) 32e509ee18Sopenharmony_ci : debugInfo_(debugInfo), wsOnMessage_(onMessage) 33e509ee18Sopenharmony_ci{} 34e509ee18Sopenharmony_ci 35e509ee18Sopenharmony_ciWsServer::~WsServer() = default; 36e509ee18Sopenharmony_ci 37e509ee18Sopenharmony_civoid WsServer::RunServer() 38e509ee18Sopenharmony_ci{ 39e509ee18Sopenharmony_ci { 40e509ee18Sopenharmony_ci std::lock_guard<std::mutex> lock(wsMutex_); 41e509ee18Sopenharmony_ci if (terminateExecution_) { 42e509ee18Sopenharmony_ci LOGE("WsServer has been terminated unexpectedly"); 43e509ee18Sopenharmony_ci return; 44e509ee18Sopenharmony_ci } 45e509ee18Sopenharmony_ci webSocket_ = std::make_unique<WebSocketServer>(); 46e509ee18Sopenharmony_ci#if !defined(OHOS_PLATFORM) 47e509ee18Sopenharmony_ci LOGI("WsSever Runsever: Init tcp websocket %{public}d", debugInfo_.port); 48e509ee18Sopenharmony_ci if (!webSocket_->InitTcpWebSocket(debugInfo_.port)) { 49e509ee18Sopenharmony_ci return; 50e509ee18Sopenharmony_ci } 51e509ee18Sopenharmony_ci#else 52e509ee18Sopenharmony_ci int runSeverInOldProcess = -2; 53e509ee18Sopenharmony_ci if (debugInfo_.socketfd == runSeverInOldProcess) { 54e509ee18Sopenharmony_ci int appPid = getprocpid(); 55e509ee18Sopenharmony_ci std::string pidStr = std::to_string(appPid); 56e509ee18Sopenharmony_ci std::string instanceIdStr(""); 57e509ee18Sopenharmony_ci 58e509ee18Sopenharmony_ci if (debugInfo_.instanceId != 0) { 59e509ee18Sopenharmony_ci instanceIdStr = std::to_string(debugInfo_.instanceId); 60e509ee18Sopenharmony_ci } 61e509ee18Sopenharmony_ci std::string sockName = pidStr + instanceIdStr + debugInfo_.componentName; 62e509ee18Sopenharmony_ci LOGI("WsServer RunServer fport localabstract: %{public}d%{public}s%{public}s", 63e509ee18Sopenharmony_ci appPid, instanceIdStr.c_str(), debugInfo_.componentName.c_str()); 64e509ee18Sopenharmony_ci if (!webSocket_->InitUnixWebSocket(sockName)) { 65e509ee18Sopenharmony_ci return; 66e509ee18Sopenharmony_ci } 67e509ee18Sopenharmony_ci } else { 68e509ee18Sopenharmony_ci LOGI("WsServer RunServer fport ark: %{public}d", debugInfo_.socketfd); 69e509ee18Sopenharmony_ci if (!webSocket_->InitUnixWebSocket(debugInfo_.socketfd)) { 70e509ee18Sopenharmony_ci return; 71e509ee18Sopenharmony_ci } 72e509ee18Sopenharmony_ci } 73e509ee18Sopenharmony_ci#endif 74e509ee18Sopenharmony_ci } 75e509ee18Sopenharmony_ci ContinueRunserver(); 76e509ee18Sopenharmony_ci} 77e509ee18Sopenharmony_civoid WsServer::ContinueRunserver() 78e509ee18Sopenharmony_ci{ 79e509ee18Sopenharmony_ci while (!terminateExecution_) { 80e509ee18Sopenharmony_ci#if !defined(OHOS_PLATFORM) 81e509ee18Sopenharmony_ci if (!webSocket_->AcceptNewConnection()) { 82e509ee18Sopenharmony_ci return; 83e509ee18Sopenharmony_ci } 84e509ee18Sopenharmony_ci#else 85e509ee18Sopenharmony_ci int runSeverInOldProcess = -2; 86e509ee18Sopenharmony_ci if (debugInfo_.socketfd == runSeverInOldProcess) { 87e509ee18Sopenharmony_ci if (!webSocket_->AcceptNewConnection()) { 88e509ee18Sopenharmony_ci return; 89e509ee18Sopenharmony_ci } 90e509ee18Sopenharmony_ci } else { 91e509ee18Sopenharmony_ci if (!webSocket_->ConnectUnixWebSocketBySocketpair()) { 92e509ee18Sopenharmony_ci return; 93e509ee18Sopenharmony_ci } 94e509ee18Sopenharmony_ci } 95e509ee18Sopenharmony_ci#endif 96e509ee18Sopenharmony_ci while (webSocket_->IsConnected()) { 97e509ee18Sopenharmony_ci std::string message = webSocket_->Decode(); 98e509ee18Sopenharmony_ci if (!message.empty() && webSocket_->IsDecodeDisconnectMsg(message)) { 99e509ee18Sopenharmony_ci LOGI("WsServer receiving disconnect msg: %{public}s", message.c_str()); 100e509ee18Sopenharmony_ci NotifyDisconnectEvent(); 101e509ee18Sopenharmony_ci } else if (!message.empty()) { 102e509ee18Sopenharmony_ci LOGI("WsServer OnMessage: %{public}s", message.c_str()); 103e509ee18Sopenharmony_ci wsOnMessage_(std::move(message)); 104e509ee18Sopenharmony_ci } 105e509ee18Sopenharmony_ci } 106e509ee18Sopenharmony_ci } 107e509ee18Sopenharmony_ci} 108e509ee18Sopenharmony_ci 109e509ee18Sopenharmony_civoid WsServer::StopServer() 110e509ee18Sopenharmony_ci{ 111e509ee18Sopenharmony_ci LOGI("WsServer StopServer"); 112e509ee18Sopenharmony_ci { 113e509ee18Sopenharmony_ci std::lock_guard<std::mutex> lock(wsMutex_); 114e509ee18Sopenharmony_ci terminateExecution_ = true; 115e509ee18Sopenharmony_ci if (webSocket_ != nullptr) { 116e509ee18Sopenharmony_ci webSocket_->Close(); 117e509ee18Sopenharmony_ci } 118e509ee18Sopenharmony_ci } 119e509ee18Sopenharmony_ci pthread_join(tid_, nullptr); 120e509ee18Sopenharmony_ci if (webSocket_ != nullptr) { 121e509ee18Sopenharmony_ci webSocket_.reset(); 122e509ee18Sopenharmony_ci } 123e509ee18Sopenharmony_ci} 124e509ee18Sopenharmony_ci 125e509ee18Sopenharmony_civoid WsServer::SendReply(const std::string& message) const 126e509ee18Sopenharmony_ci{ 127e509ee18Sopenharmony_ci std::unique_lock<std::shared_mutex> lock(g_mutex); 128e509ee18Sopenharmony_ci if (webSocket_ == nullptr) { 129e509ee18Sopenharmony_ci LOGE("WsServer SendReply websocket has been closed unexpectedly"); 130e509ee18Sopenharmony_ci return; 131e509ee18Sopenharmony_ci } 132e509ee18Sopenharmony_ci LOGI("WsServer SendReply: %{public}s", message.c_str()); 133e509ee18Sopenharmony_ci if (!webSocket_->SendReply(message)) { 134e509ee18Sopenharmony_ci LOGE("WsServer SendReply send fail"); 135e509ee18Sopenharmony_ci NotifyDisconnectEvent(); 136e509ee18Sopenharmony_ci } 137e509ee18Sopenharmony_ci} 138e509ee18Sopenharmony_ci 139e509ee18Sopenharmony_civoid WsServer::NotifyDisconnectEvent() const 140e509ee18Sopenharmony_ci{ 141e509ee18Sopenharmony_ci std::string message = "{\"id\":0, \"method\":\"Debugger.clientDisconnect\", \"params\":{}}"; 142e509ee18Sopenharmony_ci wsOnMessage_(std::move(message)); 143e509ee18Sopenharmony_ci} 144e509ee18Sopenharmony_ci} // namespace OHOS::ArkCompiler::Toolchain 145