Commit ddb69cc9 authored by Pavel Vainerman's avatar Pavel Vainerman

[uwebsocketgate]: added 'get' command

parent c0bfa359
......@@ -179,6 +179,16 @@ void UWebSocketGate::sensorInfo( const SensorMessage* sm )
s->sensorInfo(sm);
}
//--------------------------------------------------------------------------------------------
Poco::JSON::Object::Ptr UWebSocketGate::UWebSocket::to_short_json( sinfo* si )
{
Poco::JSON::Object::Ptr json = new Poco::JSON::Object();
json->set("type", "ShortSensorInfo");
json->set("error", si->err);
json->set("id", si->id);
json->set("value", si->value);
return json;
}
//--------------------------------------------------------------------------------------------
Poco::JSON::Object::Ptr UWebSocketGate::to_json( const SensorMessage* sm, const std::string& err )
{
Poco::JSON::Object::Ptr json = new Poco::JSON::Object();
......@@ -802,6 +812,14 @@ void UWebSocketGate::UWebSocket::set( uniset::ObjectId id, long value )
qcmd.push(s);
}
// -----------------------------------------------------------------------------
void UWebSocketGate::UWebSocket::get( uniset::ObjectId id )
{
sinfo s;
s.id = id;
s.cmd = "get";
qcmd.push(s);
}
// -----------------------------------------------------------------------------
void UWebSocketGate::UWebSocket::sensorInfo( const uniset::SensorMessage* sm )
{
if( cancelled )
......@@ -855,7 +873,15 @@ void UWebSocketGate::UWebSocket::doCommand( const std::shared_ptr<UInterface>& u
smap.erase(it);
}
else if( s.cmd == "set" )
{
ui->setValue(s.id, s.value);
}
else if( s.cmd == "get" )
{
s.value = ui->getValue(s.id);
s.err = "";
sendShortResponse(s);
}
s.err = "";
s.cmd = "";
......@@ -863,15 +889,29 @@ void UWebSocketGate::UWebSocket::doCommand( const std::shared_ptr<UInterface>& u
catch( std::exception& ex )
{
mycrit << "(UWebSocket::doCommand): " << ex.what() << endl;
sendError(s, ex.what());
s.err = ex.what();
sendResponse(s);
}
}
}
// -----------------------------------------------------------------------------
void UWebSocketGate::UWebSocket::sendError( sinfo& si, const std::string& err )
void UWebSocketGate::UWebSocket::sendShortResponse( sinfo& si )
{
uniset::SensorMessage sm(si.id, 0);
si.err = err;
if( jbuf.size() > maxsize )
{
mywarn << req->clientAddress().toString() << " lost messages..." << endl;
return;
}
jbuf.emplace(to_short_json(&si));
if( ioping.is_active() )
ioping.stop();
}
// -----------------------------------------------------------------------------
void UWebSocketGate::UWebSocket::sendResponse( sinfo& si )
{
uniset::SensorMessage sm(si.id, si.value);
if( jbuf.size() > maxsize )
{
......@@ -879,7 +919,7 @@ void UWebSocketGate::UWebSocket::sendError( sinfo& si, const std::string& err )
return;
}
jbuf.emplace(UWebSocketGate::to_json(&sm, err));
jbuf.emplace(UWebSocketGate::to_json(&sm, si.err));
if( ioping.is_active() )
ioping.stop();
......@@ -932,6 +972,19 @@ void UWebSocketGate::UWebSocket::onCommand( const string& cmdtxt )
// уведомление о новой команде
cmdsignal->send();
}
else if( cmd == "get" )
{
myinfo << "(websocket): " << req->clientAddress().toString()
<< "(get): " << params << endl;
auto idlist = uniset::explode(params);
for( const auto& id : idlist.getList() )
get(id);
// уведомление о новой команде
cmdsignal->send();
}
}
// -----------------------------------------------------------------------------
void UWebSocketGate::UWebSocket::write()
......
......@@ -128,6 +128,21 @@ namespace uniset
}
\endcode
\section sec_UWebSocketGate_Get Get
Функция get возвращает результат в укороченном формате
\code
{
"data": [
{
"type": "ShortSensorInfo",
"value": 63
"error": "",
"id": 10,
},
}]
}
\endcode
\section sec_UWebSocketGate_Ping Ping
Для того, чтобы соединение не закрывалось при отсутствии данных, каждые ping_sec посылается
специальное сообщение
......@@ -151,6 +166,7 @@ namespace uniset
- "set:id1=val1,id2=val2,name3=val4,..." - выставить значение датчиков
- "ask:id1,id2,name3,..." - подписаться на уведомления об изменении датчиков (sensorInfo)
- "del:id1,id2,name3,..." - отказаться от уведомления об изменении датчиков
- "get:id1,id2,name3,..." - получить текущее значение датчиков (разовое сообщение ShortSensorInfo)
*/
class UWebSocketGate:
public UniSetObject,
......@@ -262,11 +278,14 @@ namespace uniset
long value = { 0 }; // set value
};
void ask( uniset::ObjectId id );
void del( uniset::ObjectId id );
void get( uniset::ObjectId id );
void set( uniset::ObjectId id, long value );
void sensorInfo( const uniset::SensorMessage* sm );
void doCommand( const std::shared_ptr<UInterface>& ui );
static Poco::JSON::Object::Ptr to_short_json( sinfo* si );
void term();
......@@ -283,7 +302,8 @@ namespace uniset
protected:
void write();
void sendError( sinfo& si, const std::string& err );
void sendResponse( sinfo& si );
void sendShortResponse( sinfo& si );
void onCommand( const std::string& cmd );
ev::timer iosend;
......
......@@ -22,7 +22,7 @@ using namespace std;
using namespace uniset;
// -----------------------------------------------------------------------------
static int port = 8081;
static string addr("127.0.0.1"); // conf->getArgParam("--mbs-inet-addr");
static string addr("127.0.0.1");
static std::shared_ptr<UInterface> ui;
// -----------------------------------------------------------------------------
static void InitTest()
......@@ -181,3 +181,67 @@ TEST_CASE("[UWebSocketGate]: del", "[uwebsocketgate]")
REQUIRE( str.find("Ping") != string::npos );
}
// -----------------------------------------------------------------------------
TEST_CASE("[UWebSocketGate]: get", "[uwebsocketgate]")
{
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, 111);
ui->setValue(2, 222);
ui->setValue(3, 333);
std::string cmd("get:1,2,3");
ws.sendFrame(cmd.data(), (int)cmd.size());
char buffer[1024] = {};
int flags;
memset(buffer, 0, sizeof(buffer));
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": "ShortSensorInfo"...},
// {"type": "ShortSensorInfo"...},
// {"type": "ShortSensorInfo"...},
// ...
// ]
// }
auto jdata = json->get("data").extract<Poco::JSON::Array::Ptr>();
REQUIRE(jdata);
REQUIRE(jdata->size() == 3);
for( int i = 0; i < 3; i++ )
{
auto j = jdata->getObject(i);
REQUIRE(j);
REQUIRE( j->get("type").convert<std::string>() == "ShortSensorInfo" );
long id = j->get("id").convert<long>();
if( id == 1 )
{
REQUIRE( j->get("value").convert<long>() == 111 );
}
else if( id == 2 )
{
REQUIRE( j->get("value").convert<long>() == 222 );
}
else if( id == 3 )
{
REQUIRE( j->get("value").convert<long>() == 333 );
}
}
}
// -----------------------------------------------------------------------------
......@@ -9,7 +9,7 @@ cd ../../../Utilities/Admin/
cd -
./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-log-add-levels any
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