cwUi.cpp : Improve websocket msg buffering.
This commit is contained in:
parent
984cb3a11a
commit
841aa8f744
189
cwUi.cpp
189
cwUi.cpp
@ -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;
|
||||||
@ -1048,6 +1049,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
|
// buffer the incoming msg
|
||||||
opId = _labelToOpId(msg);
|
if((rc = _copy_msg_to_recv_buffer( p, void_msg, msgByteN )) != kOkRC )
|
||||||
|
goto errLabel;
|
||||||
|
|
||||||
|
// remove and and act on each buffered msg
|
||||||
switch( opId )
|
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
|
|
||||||
_onNewRemoteUi( p, wsSessId );
|
|
||||||
|
|
||||||
// Pass on the 'init' msg to the app.
|
// parse the 'opId' from the message
|
||||||
p->uiCbFunc( p->uiCbArg, wsSessId, opId, kInvalidId, kInvalidId, kInvalidId, kInvalidId, nullptr );
|
opId = _labelToOpId(msg);
|
||||||
break;
|
|
||||||
|
|
||||||
case kValueOpId:
|
|
||||||
if((ele = _parse_value_msg(p, value, (const char*)msg )) == nullptr )
|
|
||||||
cwLogError(kOpFailRC,"UI 'value' message parse failed.");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
p->uiCbFunc( p->uiCbArg, wsSessId, opId, ele->logical_parent->appId, ele->uuId, ele->appId, ele->chanId, &value );
|
|
||||||
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kCorruptOpId:
|
|
||||||
if((ele = _parse_corrupt_msg(p, (const char*)msg )) == nullptr )
|
|
||||||
cwLogError(kOpFailRC,"UI 'corrupt' message parse failed.");
|
|
||||||
else
|
|
||||||
p->uiCbFunc( p->uiCbArg, wsSessId, opId, ele->logical_parent->appId, ele->uuId, ele->appId, ele->chanId, &value );
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
|
||||||
case kClickOpId:
|
switch( opId )
|
||||||
if((ele = _parse_click_msg(p, (const char*)msg )) == nullptr )
|
{
|
||||||
cwLogError(kOpFailRC,"UI 'click' message parse failed.");
|
case kInitOpId:
|
||||||
else
|
// if the app cfg included a reference to a UI resource file then instantiate it here
|
||||||
{
|
_onNewRemoteUi( p, wsSessId );
|
||||||
p->uiCbFunc( p->uiCbArg, wsSessId, opId, ele->logical_parent->appId, ele->uuId, ele->appId, ele->chanId, &value );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kSelectOpId:
|
// Pass on the 'init' msg to the app.
|
||||||
if((ele = _parse_select_msg(p, value, (const char*)msg )) == nullptr )
|
p->uiCbFunc( p->uiCbArg, wsSessId, opId, kInvalidId, kInvalidId, kInvalidId, kInvalidId, nullptr );
|
||||||
cwLogError(kOpFailRC,"UI 'select' message parse failed.");
|
break;
|
||||||
else
|
|
||||||
{
|
|
||||||
p->uiCbFunc( p->uiCbArg, wsSessId, opId, ele->logical_parent->appId, ele->uuId, ele->appId, ele->chanId, &value );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kEchoOpId:
|
case kValueOpId:
|
||||||
if((ele = _parse_echo_msg(p,(const char*)msg)) == nullptr )
|
if((ele = _parse_value_msg(p, value, (const char*)msg )) == nullptr )
|
||||||
cwLogError(kOpFailRC,"UI Echo 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,nullptr );
|
p->uiCbFunc( p->uiCbArg, wsSessId, opId, ele->logical_parent->appId, ele->uuId, ele->appId, ele->chanId, &value );
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kIdleOpId:
|
}
|
||||||
p->uiCbFunc( p->uiCbArg, kInvalidId, opId, kInvalidId, kInvalidId, kInvalidId, kInvalidId, nullptr );
|
break;
|
||||||
break;
|
|
||||||
|
|
||||||
case kInvalidOpId:
|
case kCorruptOpId:
|
||||||
cwLogError(kInvalidIdRC,"The UI received a NULL op. id.");
|
if((ele = _parse_corrupt_msg(p, (const char*)msg )) == nullptr )
|
||||||
break;
|
cwLogError(kOpFailRC,"UI 'corrupt' message parse failed.");
|
||||||
|
else
|
||||||
|
p->uiCbFunc( p->uiCbArg, wsSessId, opId, ele->logical_parent->appId, ele->uuId, ele->appId, ele->chanId, &value );
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
|
||||||
cwLogError(kInvalidIdRC,"The UI received an unknown op. id.");
|
|
||||||
break;
|
|
||||||
|
|
||||||
} // switch opId
|
case kClickOpId:
|
||||||
|
if((ele = _parse_click_msg(p, (const char*)msg )) == nullptr )
|
||||||
|
cwLogError(kOpFailRC,"UI 'click' message parse failed.");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p->uiCbFunc( p->uiCbArg, wsSessId, opId, ele->logical_parent->appId, ele->uuId, ele->appId, ele->chanId, &value );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kSelectOpId:
|
||||||
|
if((ele = _parse_select_msg(p, value, (const char*)msg )) == nullptr )
|
||||||
|
cwLogError(kOpFailRC,"UI 'select' message parse failed.");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p->uiCbFunc( p->uiCbArg, wsSessId, opId, ele->logical_parent->appId, ele->uuId, ele->appId, ele->chanId, &value );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kEchoOpId:
|
||||||
|
if((ele = _parse_echo_msg(p,(const char*)msg)) == nullptr )
|
||||||
|
cwLogError(kOpFailRC,"UI Echo message parse failed.");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p->uiCbFunc( p->uiCbArg, wsSessId, opId, ele->logical_parent->appId, ele->uuId, ele->appId, ele->chanId,nullptr );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kIdleOpId:
|
||||||
|
p->uiCbFunc( p->uiCbArg, kInvalidId, opId, kInvalidId, kInvalidId, kInvalidId, kInvalidId, nullptr );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kInvalidOpId:
|
||||||
|
cwLogError(kInvalidIdRC,"The UI received a NULL op. id.");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
cwLogError(kInvalidIdRC,"The UI received an unknown op. id.");
|
||||||
|
break;
|
||||||
|
|
||||||
|
} // switch opId
|
||||||
|
}
|
||||||
|
errLabel:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user