From 1a11dd777e90366fd19c7103152cdb2205b820dc Mon Sep 17 00:00:00 2001 From: Sandu Liviu Catalin Date: Sun, 5 Sep 2021 13:27:19 +0300 Subject: [PATCH] Make WS non blocking and handle timeout. Implement a few helper methods as well. --- module/PocoLib/Net.cpp | 2 ++ module/PocoLib/Net.hpp | 45 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/module/PocoLib/Net.cpp b/module/PocoLib/Net.cpp index 9f99a9ca..d974a20f 100644 --- a/module/PocoLib/Net.cpp +++ b/module/PocoLib/Net.cpp @@ -33,6 +33,8 @@ void Register_POCO_Net(HSQUIRRELVM vm, Table &) .FmtFunc(_SC("SendStringFrame"), &WsClient::SendStringFrame) .Func(_SC("RecvFrame"), &WsClient::RecvFrame) .Func(_SC("RecvStringFrame"), &WsClient::RecvStringFrame) + .CbFunc(_SC("RecvFrameIn"), &WsClient::RecvFrameIn) + .CbFunc(_SC("RecvStringFrameIn"), &WsClient::RecvStringFrameIn) ); // -------------------------------------------------------------------------------------------- RootTable(vm).Bind(_SC("SqNet"), ns); diff --git a/module/PocoLib/Net.hpp b/module/PocoLib/Net.hpp index db658ea4..6952bd48 100644 --- a/module/PocoLib/Net.hpp +++ b/module/PocoLib/Net.hpp @@ -67,6 +67,7 @@ struct WsClient mRequest(Poco::Net::HTTPRequest::HTTP_GET, uri.ToStr(), Poco::Net::HTTPRequest::HTTP_1_1), mResponse(), mWebSocket(mClient, mRequest, mResponse), mBuffer(0), mFlags(0), mState(0) { + mWebSocket.setBlocking(false); // Disable blocking } /* -------------------------------------------------------------------------------------------- @@ -106,7 +107,11 @@ struct WsClient LightObj RecvFrame() { // Attempt to receive data - mState = mWebSocket.receiveFrame(mBuffer, mFlags); + try { + mState = mWebSocket.receiveFrame(mBuffer, mFlags); + } catch (const Poco::TimeoutException &) { + return LightObj{}; // We handle timeout so we can be non blocking + } // If something was returned if (mState != 0) { @@ -131,7 +136,11 @@ struct WsClient LightObj RecvStringFrame() { // Attempt to receive data - mState = mWebSocket.receiveFrame(mBuffer, mFlags); + try { + mState = mWebSocket.receiveFrame(mBuffer, mFlags); + } catch (const Poco::TimeoutException &) { + return LightObj{}; // We handle timeout so we can be non blocking + } // If something was returned if (mState != 0) { @@ -146,6 +155,38 @@ struct WsClient return LightObj{}; } + /* -------------------------------------------------------------------------------------------- + * Receives a frame from the socket and return it as a buffer. Only invokes callback if response is valid. + * The frame's payload size must not exceed the maximum payload size set with SetMaxPayloadSize(). + */ + SQInteger RecvFrameIn(Function & cb) + { + auto obj = RecvFrame(); + // Only invoke the callback if we have a valid response + if (mState != 0 || mFlags != 0) + { + cb(obj, mState, mFlags); + } + // Return result + return mState; + } + + /* -------------------------------------------------------------------------------------------- + * Receives a frame from the socket and return it as a string. Only invokes callback if response is valid. + * The frame's payload size must not exceed the maximum payload size set with SetMaxPayloadSize(). + */ + SQInteger RecvStringFrameIn(Function & cb) + { + auto obj = RecvStringFrame(); + // Only invoke the callback if we have data response + if (mState != 0 || mFlags != 0) + { + cb(obj, mState, mFlags); + } + // Return result + return mState; + } + /* -------------------------------------------------------------------------------------------- * Sets the maximum payload size for RecvFrame(). The default is std::numeric_limits::max(). */