cwUi.cpp : Improve websocket msg buffering.

This commit is contained in:
kevin 2022-09-10 10:18:52 -04:00
parent 984cb3a11a
commit 841aa8f744

189
cwUi.cpp
View File

@ -89,6 +89,7 @@ namespace cw
char* recvBuf; char* recvBuf;
unsigned recvBufN; unsigned recvBufN;
unsigned recvBufIdx; unsigned recvBufIdx;
unsigned recvShiftN;
unsigned* sessA; // sessA[ sessN ] array of wsSessId's unsigned* sessA; // sessA[ sessN ] array of wsSessId's
unsigned sessN; unsigned sessN;
@ -1047,6 +1048,49 @@ namespace cw
{ {
return _setPropertyValue( h, propertyStr,uuId,enableFl ? 1 : 0 ); return _setPropertyValue( h, propertyStr,uuId,enableFl ? 1 : 0 );
} }
rc_t _copy_msg_to_recv_buffer( ui_t* p, const void* msg, unsigned msgByteN )
{
rc_t rc;
if( p->recvBufIdx + msgByteN > p->recvBufN )
rc = cwLogError(kBufTooSmallRC,"The UI input buffer (%i) is too small.", p->recvBufN);
else
{
memcpy(p->recvBuf + p->recvBufIdx, msg, msgByteN );
p->recvBufIdx += msgByteN;
}
return rc;
}
const char* _get_msg_from_recv_buffer( ui_t* p )
{
const char* msg = nullptr;
unsigned i;
// shift off the previous msg
if( p->recvShiftN > 0 )
{
memmove(p->recvBuf, p->recvBuf+p->recvShiftN, p->recvBufIdx - p->recvShiftN );
p->recvShiftN = 0;
}
// locate the end of the next msg.
for(i=0; p->recvBuf[i]!=0 and i<p->recvBufIdx; ++i)
{}
// if the end of the next msg was found
if( p->recvBuf[i] == 0 )
{
p->recvShiftN = i+1;
msg = p->recvBuf;
}
return msg;
}
} }
} }
@ -1089,6 +1133,7 @@ cw::rc_t cw::ui::create(
p->recvBuf = mem::allocZ<char>(fmtBufByteN); p->recvBuf = mem::allocZ<char>(fmtBufByteN);
p->recvBufN = fmtBufByteN; p->recvBufN = fmtBufByteN;
p->recvBufIdx = 0; p->recvBufIdx = 0;
p->recvShiftN = 0;
// create the root element // create the root element
if((ele = _createBaseEle(p, nullptr, kRootAppId, kInvalidId, "uiDivId" )) == nullptr || ele->uuId != kRootUuId ) if((ele = _createBaseEle(p, nullptr, kRootAppId, kInvalidId, "uiDivId" )) == nullptr || ele->uuId != kRootUuId )
@ -1191,12 +1236,14 @@ cw::rc_t cw::ui::onDisconnect( handle_t h, unsigned wsSessId )
cw::rc_t cw::ui::onReceive( handle_t h, unsigned wsSessId, const void* void_msg, unsigned msgByteN ) cw::rc_t cw::ui::onReceive( handle_t h, unsigned wsSessId, const void* void_msg, unsigned msgByteN )
{ {
rc_t rc = kOkRC; rc_t rc = kOkRC;
ui_t* p = _handleToPtr(h); ui_t* p = _handleToPtr(h);
opId_t opId = kInvalidOpId; opId_t opId = kInvalidOpId;
value_t value; ele_t* ele = nullptr;
ele_t* ele; const char* msg = nullptr;
value_t value;
/*
const char* src_msg = (const char*)void_msg; const char* src_msg = (const char*)void_msg;
const char* msg = src_msg; const char* msg = src_msg;
@ -1233,80 +1280,90 @@ cw::rc_t cw::ui::onReceive( handle_t h, unsigned wsSessId, const void* void_msg,
// the message is being processed so the buffer will end up empty // the message is being processed so the buffer will end up empty
// (if it was being used) // (if it was being used)
p->recvBufIdx = 0; p->recvBufIdx = 0;
*/
// parse the 'opId' from the message
opId = _labelToOpId(msg);
// buffer the incoming msg
switch( opId ) if((rc = _copy_msg_to_recv_buffer( p, void_msg, msgByteN )) != kOkRC )
goto errLabel;
// remove and and act on each buffered msg
while( (msg = _get_msg_from_recv_buffer(p)) != NULL )
{ {
case kInitOpId:
// if the app cfg included a reference to a UI resource file then instantiate it here // parse the 'opId' from the message
_onNewRemoteUi( p, wsSessId ); opId = _labelToOpId(msg);
switch( opId )
{
case kInitOpId:
// if the app cfg included a reference to a UI resource file then instantiate it here
_onNewRemoteUi( p, wsSessId );
// Pass on the 'init' msg to the app. // Pass on the 'init' msg to the app.
p->uiCbFunc( p->uiCbArg, wsSessId, opId, kInvalidId, kInvalidId, kInvalidId, kInvalidId, nullptr ); p->uiCbFunc( p->uiCbArg, wsSessId, opId, kInvalidId, kInvalidId, kInvalidId, kInvalidId, nullptr );
break; break;
case kValueOpId: case kValueOpId:
if((ele = _parse_value_msg(p, value, (const char*)msg )) == nullptr ) if((ele = _parse_value_msg(p, value, (const char*)msg )) == nullptr )
cwLogError(kOpFailRC,"UI 'value' message parse failed."); cwLogError(kOpFailRC,"UI 'value' message parse failed.");
else else
{ {
p->uiCbFunc( p->uiCbArg, wsSessId, opId, ele->logical_parent->appId, ele->uuId, ele->appId, ele->chanId, &value ); p->uiCbFunc( p->uiCbArg, wsSessId, opId, ele->logical_parent->appId, ele->uuId, ele->appId, ele->chanId, &value );
} }
break; break;
case kCorruptOpId: case kCorruptOpId:
if((ele = _parse_corrupt_msg(p, (const char*)msg )) == nullptr ) if((ele = _parse_corrupt_msg(p, (const char*)msg )) == nullptr )
cwLogError(kOpFailRC,"UI 'corrupt' message parse failed."); cwLogError(kOpFailRC,"UI 'corrupt' message parse failed.");
else else
p->uiCbFunc( p->uiCbArg, wsSessId, opId, ele->logical_parent->appId, ele->uuId, ele->appId, ele->chanId, &value ); p->uiCbFunc( p->uiCbArg, wsSessId, opId, ele->logical_parent->appId, ele->uuId, ele->appId, ele->chanId, &value );
break; break;
case kClickOpId: case kClickOpId:
if((ele = _parse_click_msg(p, (const char*)msg )) == nullptr ) if((ele = _parse_click_msg(p, (const char*)msg )) == nullptr )
cwLogError(kOpFailRC,"UI 'click' message parse failed."); cwLogError(kOpFailRC,"UI 'click' message parse failed.");
else else
{ {
p->uiCbFunc( p->uiCbArg, wsSessId, opId, ele->logical_parent->appId, ele->uuId, ele->appId, ele->chanId, &value ); p->uiCbFunc( p->uiCbArg, wsSessId, opId, ele->logical_parent->appId, ele->uuId, ele->appId, ele->chanId, &value );
} }
break; break;
case kSelectOpId: case kSelectOpId:
if((ele = _parse_select_msg(p, value, (const char*)msg )) == nullptr ) if((ele = _parse_select_msg(p, value, (const char*)msg )) == nullptr )
cwLogError(kOpFailRC,"UI 'select' message parse failed."); cwLogError(kOpFailRC,"UI 'select' message parse failed.");
else else
{ {
p->uiCbFunc( p->uiCbArg, wsSessId, opId, ele->logical_parent->appId, ele->uuId, ele->appId, ele->chanId, &value ); p->uiCbFunc( p->uiCbArg, wsSessId, opId, ele->logical_parent->appId, ele->uuId, ele->appId, ele->chanId, &value );
} }
break; break;
case kEchoOpId: case kEchoOpId:
if((ele = _parse_echo_msg(p,(const char*)msg)) == nullptr ) if((ele = _parse_echo_msg(p,(const char*)msg)) == nullptr )
cwLogError(kOpFailRC,"UI Echo message parse failed."); cwLogError(kOpFailRC,"UI Echo message parse failed.");
else else
{ {
p->uiCbFunc( p->uiCbArg, wsSessId, opId, ele->logical_parent->appId, ele->uuId, ele->appId, ele->chanId,nullptr ); p->uiCbFunc( p->uiCbArg, wsSessId, opId, ele->logical_parent->appId, ele->uuId, ele->appId, ele->chanId,nullptr );
} }
break; break;
case kIdleOpId: case kIdleOpId:
p->uiCbFunc( p->uiCbArg, kInvalidId, opId, kInvalidId, kInvalidId, kInvalidId, kInvalidId, nullptr ); p->uiCbFunc( p->uiCbArg, kInvalidId, opId, kInvalidId, kInvalidId, kInvalidId, kInvalidId, nullptr );
break; break;
case kInvalidOpId: case kInvalidOpId:
cwLogError(kInvalidIdRC,"The UI received a NULL op. id."); cwLogError(kInvalidIdRC,"The UI received a NULL op. id.");
break; break;
default: default:
cwLogError(kInvalidIdRC,"The UI received an unknown op. id."); cwLogError(kInvalidIdRC,"The UI received an unknown op. id.");
break; break;
} // switch opId } // switch opId
}
errLabel:
return rc; return rc;
} }