diff --git a/frameworks/cj/websocket/include/ffi_structs.h b/frameworks/cj/websocket/include/ffi_structs.h index 8f3b0ed66faa0ac8ad682489070cf155ce77d191..7254bc85ef88e410b820f7810c034ba1762e7fca 100644 --- a/frameworks/cj/websocket/include/ffi_structs.h +++ b/frameworks/cj/websocket/include/ffi_structs.h @@ -49,6 +49,7 @@ EXTERN_C_START char* protocol; bool usingSystemProxy; CHttpProxy* httpProxy; + uint32_t pingPongTime; }; struct CWebSocketCloseOptions { diff --git a/frameworks/js/napi/websocket/async_context/include/connect_context.h b/frameworks/js/napi/websocket/async_context/include/connect_context.h index 4614fd5b231fc6bfe0f15f46fca1ce0878796d6a..ea5f99409a73c96a45350740010361aab7b388e8 100755 --- a/frameworks/js/napi/websocket/async_context/include/connect_context.h +++ b/frameworks/js/napi/websocket/async_context/include/connect_context.h @@ -95,6 +95,14 @@ public: std::string bundleName_; + const static std::uint32_t defaultPingPongTime = 30; + + const static std::uint32_t minPingPongTime = 0; + + const static std::uint32_t maxPingPongTime = 30000; + + std::uint32_t pingPongTime_ = defaultPingPongTime; + private: std::string userCertPath_; @@ -110,6 +118,8 @@ private: bool ParseProtocol(napi_value optionsValue); + void ParsePingPongTime(napi_value optionsValue); + bool CheckParamsType(napi_value *params, size_t paramsCount); void ParseCallback(napi_value const *params, size_t paramsCount); diff --git a/frameworks/js/napi/websocket/async_context/src/connect_context.cpp b/frameworks/js/napi/websocket/async_context/src/connect_context.cpp index bd9c78bd4532e02431753397958e21a7805cf1f0..3d63a3bd9bc06bfe0f889bb1cb348ed0442d3ba6 100644 --- a/frameworks/js/napi/websocket/async_context/src/connect_context.cpp +++ b/frameworks/js/napi/websocket/async_context/src/connect_context.cpp @@ -79,6 +79,7 @@ void ConnectContext::ParseParams(napi_value *params, size_t paramsCount) ParseCaPath(params[1]); ParseClientCert(params[1]); ParseSkipServerCertVerify(params[1]); + ParsePingPongTime(params[1]); if (!ParseProxy(params[1]) || !ParseProtocol(params[1])) { return; } @@ -125,6 +126,7 @@ void ConnectContext::ParseParamsCountThree(napi_value const *params) ParseCaPath(params[1]); ParseClientCert(params[1]); ParseSkipServerCertVerify(params[1]); + ParsePingPongTime(params[1]); if (!ParseProxy(params[1]) || !ParseProtocol(params[1])) { if (NapiUtils::GetValueType(GetEnv(), params[FUNCTION_PARAM_THREE - 1]) == napi_function) { SetCallback(params[FUNCTION_PARAM_THREE - 1]); @@ -280,6 +282,20 @@ bool ConnectContext::ParseProtocol(napi_value optionsValue) return false; } +void ConnectContext::ParsePingPongTime(napi_value optionsValue) +{ + if (!NapiUtils::HasNamedProperty(GetEnv(), optionsValue, ContextKey::PINGPONG_TIME)) { + NETSTACK_LOGI("ConnectContext PINGPONG_TIME not found"); + return; + } + napi_value jsPingPongTime = NapiUtils::GetNamedProperty(GetEnv(), optionsValue, ContextKey::PINGPONG_TIME); + if (NapiUtils::GetValueType(GetEnv(), jsPingPongTime) != napi_number) { + NETSTACK_LOGE("ConnectContext PINGPONG_TIME is not napi_number"); + return; + } + pingPongTime_ = NapiUtils::GetUint32FromValue(GetEnv(), jsPingPongTime); +} + bool ConnectContext::CheckParamsType(napi_value *params, size_t paramsCount) { if (paramsCount == FUNCTION_PARAM_ONE) { diff --git a/frameworks/js/napi/websocket/constant/include/constant.h b/frameworks/js/napi/websocket/constant/include/constant.h index fddd15051aed669b0517aebf8d4cb12a64328891..71dfa22beac3febb2209a548114ae63333a8ec92 100644 --- a/frameworks/js/napi/websocket/constant/include/constant.h +++ b/frameworks/js/napi/websocket/constant/include/constant.h @@ -110,6 +110,7 @@ public: static const char *SERVER_IP; static const char *SERVER_CERT; static const char *PROTOCOL; + static const char *PINGPONG_TIME; }; class EventName final { diff --git a/frameworks/js/napi/websocket/constant/src/constant.cpp b/frameworks/js/napi/websocket/constant/src/constant.cpp index 2006cb5d92a8ce152d1f0dce8e71889057197017..9646732bb54822184cffd05ba67c92717a50a0d8 100644 --- a/frameworks/js/napi/websocket/constant/src/constant.cpp +++ b/frameworks/js/napi/websocket/constant/src/constant.cpp @@ -35,6 +35,7 @@ const char *ContextKey::MAX_CONNECTIONS_FOR_ONE_CLIENT = "maxConnectionsForOneCl const char *ContextKey::SERVER_IP = "serverIP"; const char *ContextKey::SERVER_CERT = "serverCert"; const char *ContextKey::PROTOCOL = "protocol"; +const char *ContextKey::PINGPONG_TIME = "pingPongTime"; const char *ContextKey::PROXY = "proxy"; const char *ContextKey::PROTCOL = "protocol"; diff --git a/frameworks/js/napi/websocket/websocket_exec/src/websocket_exec.cpp b/frameworks/js/napi/websocket/websocket_exec/src/websocket_exec.cpp index 8e8f9e42abac3f91714692fd1d9cd0fdf8e17d36..f6bd1a3229e8996b67779ed435580f3cc4a464cd 100644 --- a/frameworks/js/napi/websocket/websocket_exec/src/websocket_exec.cpp +++ b/frameworks/js/napi/websocket/websocket_exec/src/websocket_exec.cpp @@ -89,7 +89,7 @@ static const lws_protocols LWS_PROTOCOLS[] = { {nullptr, nullptr, 0, 0}, // this line is needed }; -static const lws_retry_bo_t RETRY = { +static lws_retry_bo_t retry = { .secs_since_valid_ping = 30, .secs_since_valid_hangup = 60, .jitter_percent = 20, @@ -538,6 +538,20 @@ static bool WebSocketConnect(lws_client_connect_info &connectInfo, const std::sh return true; } +void SetRetry(lws_retry_bo_t &retry, ConnectContext *context) +{ + if (context == nullptr) { + return; + } + if (context->pingPongTime_ < context->minPingPongTime || context->pingPongTime_ > context->maxPingPongTime) { + NETSTACK_LOGE("PingPongTime is invalid: %{public}d", context->pingPongTime_); + context->pingPongTime_ = context->defaultPingPongTime; + } + NETSTACK_LOGI("PingPongTime is : %{public}d", context->pingPongTime_); + retry.secs_since_valid_ping = context->pingPongTime_; + retry.secs_since_valid_hangup = context->pingPongTime_ + context->pingPongTime_; +} + bool WebSocketExec::CreatConnectInfo(ConnectContext *context, lws_context *lwsContext, const std::shared_ptr &manager) { @@ -581,9 +595,10 @@ bool WebSocketExec::CreatConnectInfo(ConnectContext *context, lws_context *lwsCo NETSTACK_LOGI("ExecConnect skip server cert verify"); connectInfo.ssl_connection = ((unsigned int)connectInfo.ssl_connection) | LCCSCF_ALLOW_INSECURE; } + SetRetry(retry, context); lws *wsi = nullptr; connectInfo.pwsi = &wsi; - connectInfo.retry_and_idle_policy = &RETRY; + connectInfo.retry_and_idle_policy = &retry; connectInfo.userdata = manager.get(); if (!WebSocketConnect(connectInfo, manager, context)) { return false; diff --git a/interfaces/kits/js/@ohos.net.webSocket.d.ts b/interfaces/kits/js/@ohos.net.webSocket.d.ts index 26af71eb57657a60c29c10f49e7e4a6dff160ebc..6b4a906e79b25ef850b86c2cd4beb27f2191c2a8 100644 --- a/interfaces/kits/js/@ohos.net.webSocket.d.ts +++ b/interfaces/kits/js/@ohos.net.webSocket.d.ts @@ -171,6 +171,18 @@ declare namespace webSocket { * @since 12 */ protocol?: string; + + /** + * Self defined ping pong time. + * default: 30. disable: 0. max: 30000. unit: second. + * Ping is performed at every pingPongTime interval. + * If no pong is received within the pingPongTime period, the websocket connection will be disconnected. + * @type {?number} + * @syscap SystemCapability.Communication.NetStack + * @since 21 + * @arkts 1.2 + */ + pingPongTime?: number; } /**