Commit f851912c authored by Pavel Vainerman's avatar Pavel Vainerman

[uwebsocket]: fixed "max command processing"

parent ddb69cc9
...@@ -78,10 +78,10 @@ UWebSocketGate::UWebSocketGate( uniset::ObjectId id, xmlNode* cnode, const strin ...@@ -78,10 +78,10 @@ UWebSocketGate::UWebSocketGate( uniset::ObjectId id, xmlNode* cnode, const strin
setMaxSizeOfMessageQueue(sz); setMaxSizeOfMessageQueue(sz);
#ifndef DISABLE_REST_API #ifndef DISABLE_REST_API
wsHeartbeatTime_sec = (float)conf->getArgPInt("--" + prefix + "ws-heartbeat-time", it.getProp("wsHeartbeatTimeTime"), int(wsHeartbeatTime_sec * 1000)) / 1000.0; wsHeartbeatTime_sec = (float)conf->getArgPInt("--" + prefix + "heartbeat-time", it.getProp("wsHeartbeatTimeTime"), int(wsHeartbeatTime_sec * 1000)) / 1000.0;
wsSendTime_sec = (float)conf->getArgPInt("--" + prefix + "ws-send-time", it.getProp("wsSendTime"), int(wsSendTime_sec * 1000.0)) / 1000.0; wsSendTime_sec = (float)conf->getArgPInt("--" + prefix + "send-time", it.getProp("wsSendTime"), int(wsSendTime_sec * 1000.0)) / 1000.0;
wsMaxSend = conf->getArgPInt("--" + prefix + "ws-max-send", it.getProp("wsMaxSend"), wsMaxSend); wsMaxSend = conf->getArgPInt("--" + prefix + "max-send", it.getProp("wsMaxSend"), wsMaxSend);
wsMaxCmd = conf->getArgPInt("--" + prefix + "ws-max-cmd", it.getProp("wsMaxCmd"), wsMaxCmd); wsMaxCmd = conf->getArgPInt("--" + prefix + "max-cmd", it.getProp("wsMaxCmd"), wsMaxCmd);
httpHost = conf->getArgParam("--" + prefix + "httpserver-host", "localhost"); httpHost = conf->getArgParam("--" + prefix + "httpserver-host", "localhost");
httpPort = conf->getArgPInt("--" + prefix + "httpserver-port", 8081); httpPort = conf->getArgPInt("--" + prefix + "httpserver-port", 8081);
...@@ -239,11 +239,11 @@ void UWebSocketGate::help_print() ...@@ -239,11 +239,11 @@ void UWebSocketGate::help_print()
cout << "--prefix-max-messages-processing num - Количество uniset-сообщений обрабатывамых за один раз. По умолчанию 50. По умолчанию: 100" << endl; cout << "--prefix-max-messages-processing num - Количество uniset-сообщений обрабатывамых за один раз. По умолчанию 50. По умолчанию: 100" << endl;
cout << "websockets: " << endl; cout << "websockets: " << endl;
cout << "--prefix-ws-max num - Максимальное количество websocket-ов" << endl; cout << "--prefix-max num - Максимальное количество websocket-ов" << endl;
cout << "--prefix-ws-heartbeat-time msec - Период сердцебиения в соединении. По умолчанию: 3000 мсек" << endl; cout << "--prefix-heartbeat-time msec - Период сердцебиения в соединении. По умолчанию: 3000 мсек" << endl;
cout << "--prefix-ws-send-time msec - Период посылки сообщений. По умолчанию: 500 мсек" << endl; cout << "--prefix-send-time msec - Период посылки сообщений. По умолчанию: 500 мсек" << endl;
cout << "--prefix-ws-max num - Максимальное число сообщений посылаемых за один раз. По умолчанию: 200" << endl; cout << "--prefix-max-send num - Максимальное число сообщений посылаемых за один раз. По умолчанию: 200" << endl;
cout << "--prefix-ws-cmd num - Максимальное число команд обрабатываемых за один раз. По умолчанию: 100" << endl; cout << "--prefix-max-cmd num - Максимальное число команд обрабатываемых за один раз. По умолчанию: 200" << endl;
cout << "http: " << endl; cout << "http: " << endl;
cout << "--prefix-httpserver-host ip - IP на котором слушает http сервер. По умолчанию: localhost" << endl; cout << "--prefix-httpserver-host ip - IP на котором слушает http сервер. По умолчанию: localhost" << endl;
...@@ -304,8 +304,8 @@ void UWebSocketGate::onActivate( ev::async& watcher, int revents ) ...@@ -304,8 +304,8 @@ void UWebSocketGate::onActivate( ev::async& watcher, int revents )
{ {
if( !s->isActive() ) if( !s->isActive() )
{ {
s->doCommand(ui);
s->set(loop, wscmd); s->set(loop, wscmd);
s->doCommand(ui);
} }
} }
} }
...@@ -844,6 +844,9 @@ void UWebSocketGate::UWebSocket::sensorInfo( const uniset::SensorMessage* sm ) ...@@ -844,6 +844,9 @@ void UWebSocketGate::UWebSocket::sensorInfo( const uniset::SensorMessage* sm )
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void UWebSocketGate::UWebSocket::doCommand( const std::shared_ptr<UInterface>& ui ) void UWebSocketGate::UWebSocket::doCommand( const std::shared_ptr<UInterface>& ui )
{ {
if( qcmd.empty() )
return;
for( size_t i = 0; i < maxcmd && !qcmd.empty(); i++ ) for( size_t i = 0; i < maxcmd && !qcmd.empty(); i++ )
{ {
auto s = qcmd.front(); auto s = qcmd.front();
...@@ -893,6 +896,9 @@ void UWebSocketGate::UWebSocket::doCommand( const std::shared_ptr<UInterface>& u ...@@ -893,6 +896,9 @@ void UWebSocketGate::UWebSocket::doCommand( const std::shared_ptr<UInterface>& u
sendResponse(s); sendResponse(s);
} }
} }
if( !qcmd.empty() && cmdsignal )
cmdsignal->send();
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void UWebSocketGate::UWebSocket::sendShortResponse( sinfo& si ) void UWebSocketGate::UWebSocket::sendShortResponse( sinfo& si )
......
...@@ -166,7 +166,7 @@ namespace uniset ...@@ -166,7 +166,7 @@ namespace uniset
- "set:id1=val1,id2=val2,name3=val4,..." - выставить значение датчиков - "set:id1=val1,id2=val2,name3=val4,..." - выставить значение датчиков
- "ask:id1,id2,name3,..." - подписаться на уведомления об изменении датчиков (sensorInfo) - "ask:id1,id2,name3,..." - подписаться на уведомления об изменении датчиков (sensorInfo)
- "del:id1,id2,name3,..." - отказаться от уведомления об изменении датчиков - "del:id1,id2,name3,..." - отказаться от уведомления об изменении датчиков
- "get:id1,id2,name3,..." - получить текущее значение датчиков (разовое сообщение ShortSensorInfo) - "get:id1,id2,name3,..." - получить текущее значение датчиков (разовое сообщение ShortSensorInfo)
*/ */
class UWebSocketGate: class UWebSocketGate:
public UniSetObject, public UniSetObject,
......
...@@ -2,4 +2,4 @@ ...@@ -2,4 +2,4 @@
ulimit -Sc 1000000 ulimit -Sc 1000000
uniset2-start.sh -f ./uniset2-wsgate --confile test.xml --ws-name UWebSocketGate1 --ws-log-add-levels any $* uniset2-start.sh -f ./uniset2-wsgate --confile test.xml --ws-name UWebSocketGate1 --ws-log-add-levels any --ws-max-cmd 3 $*
...@@ -129,7 +129,6 @@ TEST_CASE("[UWebSocketGate]: ask", "[uwebsocketgate]") ...@@ -129,7 +129,6 @@ TEST_CASE("[UWebSocketGate]: ask", "[uwebsocketgate]")
// sensorInfo // sensorInfo
ui->setValue(2, 84); ui->setValue(2, 84);
memset(buffer, 0, sizeof(buffer)); memset(buffer, 0, sizeof(buffer));
ws.receiveFrame(buffer, sizeof(buffer), flags); ws.receiveFrame(buffer, sizeof(buffer), flags);
...@@ -146,7 +145,95 @@ TEST_CASE("[UWebSocketGate]: ask", "[uwebsocketgate]") ...@@ -146,7 +145,95 @@ TEST_CASE("[UWebSocketGate]: ask", "[uwebsocketgate]")
REQUIRE( j->get("type").convert<std::string>() == "SensorInfo" ); REQUIRE( j->get("type").convert<std::string>() == "SensorInfo" );
REQUIRE( j->get("iotype").convert<std::string>() == "AI" ); REQUIRE( j->get("iotype").convert<std::string>() == "AI" );
REQUIRE( j->get("value").convert<long>() == 84 ); REQUIRE( j->get("value").convert<long>() == 84 );
}
// -----------------------------------------------------------------------------
TEST_CASE("[UWebSocketGate]: ask max", "[uwebsocketgate][cmdmax]")
{
try
{
InitTest();
HTTPClientSession cs(addr, port);
HTTPRequest request(HTTPRequest::HTTP_GET, "/wsgate", HTTPRequest::HTTP_1_1);
HTTPResponse response;
WebSocket ws(cs, request, response);
ui->setValue(1, 1);
ui->setValue(2, 42);
ui->setValue(3, 42);
ui->setValue(4, 1);
ui->setValue(5, 42);
ui->setValue(6, 42);
std::string cmd("ask:1,2,3,4,5,6");
ws.sendFrame(cmd.data(), (int)cmd.size());
char buffer[1024] = {};
int flags;
ws.receiveFrame(buffer, sizeof(buffer), flags);
REQUIRE(flags == WebSocket::FRAME_TEXT);
Poco::JSON::Parser parser;
auto result = parser.parse(buffer);
Poco::JSON::Object::Ptr json = result.extract<Poco::JSON::Object::Ptr>();
REQUIRE(json);
// {
// "data": [
// {"type": "SensorInfo"...},
// {"type": "SensorInfo"...},
// {"type": "SensorInfo"...}
// ...
// ]
// }
auto jdata = json->get("data").extract<Poco::JSON::Array::Ptr>();
REQUIRE(jdata);
REQUIRE(jdata->size() == 6);
for( int i = 0; i < 6; i++ )
{
auto j = jdata->getObject(i);
REQUIRE(j);
REQUIRE( j->get("type").convert<std::string>() == "SensorInfo" );
long id = j->get("id").convert<long>();
if( id == 1 || id == 3 )
{
REQUIRE( j->get("iotype").convert<std::string>() == "DI" );
REQUIRE( j->get("value").convert<long>() == 1 );
}
else
{
REQUIRE( j->get("iotype").convert<std::string>() == "AI" );
REQUIRE( j->get("value").convert<long>() == 42 );
}
}
// sensorInfo
ui->setValue(2, 84);
memset(buffer, 0, sizeof(buffer));
ws.receiveFrame(buffer, sizeof(buffer), flags);
REQUIRE(flags == WebSocket::FRAME_TEXT);
result = parser.parse(buffer);
json = result.extract<Poco::JSON::Object::Ptr>();
REQUIRE(json);
jdata = json->get("data").extract<Poco::JSON::Array::Ptr>();
REQUIRE(jdata);
REQUIRE(jdata->size() == 1);
auto j = jdata->getObject(0);
REQUIRE(j);
REQUIRE( j->get("type").convert<std::string>() == "SensorInfo" );
REQUIRE( j->get("iotype").convert<std::string>() == "AI" );
REQUIRE( j->get("value").convert<long>() == 84 );
} // TODO: WTF?
catch( std::exception& ex ) {}
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
TEST_CASE("[UWebSocketGate]: del", "[uwebsocketgate]") TEST_CASE("[UWebSocketGate]: del", "[uwebsocketgate]")
......
...@@ -9,7 +9,8 @@ cd ../../../Utilities/Admin/ ...@@ -9,7 +9,8 @@ cd ../../../Utilities/Admin/
cd - cd -
./uniset2-start.sh -f ./tests-with-sm $* -- --confile uwebsocketgate-test-configure.xml --e-startup-pause 10 \ ./uniset2-start.sh -f ./tests-with-sm $* -- --confile uwebsocketgate-test-configure.xml --e-startup-pause 10 \
--ws-name UWebSocketGate1 --ws-httpserverhost-addr 127.0.0.1 --ws-httpserver-port 8081 --ws-name UWebSocketGate1 --ws-httpserverhost-addr 127.0.0.1 --ws-httpserver-port 8081 --ws-max-cmd 3
#--ws-log-add-levels any
# --ws-log-add-levels any
...@@ -46,6 +46,9 @@ ...@@ -46,6 +46,9 @@
<item id="1" iotype="DI" name="DI1_S" textname="DI sensor 1"/> <item id="1" iotype="DI" name="DI1_S" textname="DI sensor 1"/>
<item id="2" iotype="AI" name="AI1_S" textname="AI sensor 1" default="2" undefined_value="65635"/> <item id="2" iotype="AI" name="AI1_S" textname="AI sensor 1" default="2" undefined_value="65635"/>
<item id="3" iotype="AI" name="AI2_S" textname="AI sensor 2" default="3"/> <item id="3" iotype="AI" name="AI2_S" textname="AI sensor 2" default="3"/>
<item id="4" iotype="DI" name="DI2_S" textname="DI sensor 2"/>
<item id="5" iotype="AI" name="AI3_S" textname="AI sensor 3" default="2" undefined_value="65635"/>
<item id="6" iotype="AI" name="AI4_S" textname="AI sensor 4" default="3"/>
</sensors> </sensors>
<thresholds/> <thresholds/>
<controllers name="Controllers"> <controllers name="Controllers">
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment