diff --git a/unity/Assets/core/upm/Runtime/Resources/puerts/websocketpp.mjs b/unity/Assets/core/upm/Runtime/Resources/puerts/websocketpp.mjs index ddee2a6203..37da6e26da 100644 --- a/unity/Assets/core/upm/Runtime/Resources/puerts/websocketpp.mjs +++ b/unity/Assets/core/upm/Runtime/Resources/puerts/websocketpp.mjs @@ -83,6 +83,12 @@ class WebSocket extends EventTarget { } get readyState() { + if (this._readyState === WebSocket.OPEN) { + const [statue, message] = this._raw.statue(); + if (statue != 0) { + this._fail(`${message}[${statue}]`); + } + } return this._readyState; } diff --git a/unity/test/Src/Cases/WebsocketTest.cs b/unity/test/Src/Cases/WebsocketTest.cs index 88fa464c23..60b7d14023 100644 --- a/unity/test/Src/Cases/WebsocketTest.cs +++ b/unity/test/Src/Cases/WebsocketTest.cs @@ -111,6 +111,9 @@ public async Task SmokeTest() con.addEventListener('open', (ev) => { console.log(`on open`); con.send('puerts websocket'); + if (con.readyState != WebSocket.OPEN) { + throw new Error('invalid readyState'); + } }); con.addEventListener('message', (ev) => { console.log(`on message: ${ev.data}`); diff --git a/unreal/Puerts/Source/JsEnv/Private/WebSocketImpl.cpp b/unreal/Puerts/Source/JsEnv/Private/WebSocketImpl.cpp index ae874d0a41..a28d9c7b41 100644 --- a/unreal/Puerts/Source/JsEnv/Private/WebSocketImpl.cpp +++ b/unreal/Puerts/Source/JsEnv/Private/WebSocketImpl.cpp @@ -109,6 +109,8 @@ class V8WebSocketClientImpl void Close(const v8::FunctionCallbackInfo& Info); + void Statue(const v8::FunctionCallbackInfo& Info); + void CloseImmediately(websocketpp::close::status::value const code, std::string const& reason); void PollOne(); @@ -309,6 +311,20 @@ void V8WebSocketClientImpl::Close(const v8::FunctionCallbackInfo& Inf Cleanup(); } +void V8WebSocketClientImpl::Statue(const v8::FunctionCallbackInfo& Info) +{ + websocketpp::lib::error_code ec; + Client.ping(Handle, "", ec); + auto isolate = Info.GetIsolate(); + auto context = isolate->GetCurrentContext(); + auto res = v8::Array::New(isolate); + + res->Set(context, 0, v8::Int32::New(isolate, ec.value())).Check(); + res->Set(context, 1, + v8::String::NewFromUtf8(isolate, ec.message().c_str(), v8::NewStringType::kNormal, ec.message().size()).ToLocalChecked()); + Info.GetReturnValue().Set(res); +} + void V8WebSocketClientImpl::CloseImmediately(websocketpp::close::status::value const code, std::string const& reason) { if (!Handle.expired()) @@ -444,6 +460,13 @@ void InitWebsocketPPWrap(v8::Local Context) ->Close(Info); })); + WSTemplate->PrototypeTemplate()->Set(v8::String::NewFromUtf8(Isolate, "statue").ToLocalChecked(), + v8::FunctionTemplate::New(Isolate, + [](const v8::FunctionCallbackInfo& Info) { + static_cast(Info.Holder()->GetAlignedPointerFromInternalField(0)) + ->Statue(Info); + })); + WSTemplate->PrototypeTemplate()->Set(v8::String::NewFromUtf8(Isolate, "poll").ToLocalChecked(), v8::FunctionTemplate::New(Isolate, [](const v8::FunctionCallbackInfo& Info)