Commit 36839d01 authored by Pavel Vainerman's avatar Pavel Vainerman

backported to p9 as 2.9.4-alt0.M90P.0.1 (with rpmbph script)

parents c4d818e4 ddb69cc9
...@@ -26,8 +26,8 @@ ...@@ -26,8 +26,8 @@
%define oname uniset2 %define oname uniset2
Name: libuniset2 Name: libuniset2
Version: 2.9.3 Version: 2.9.4
Release: alt1.M90P.2 Release: alt0.M90P.0.1
Summary: UniSet - library for building distributed industrial control systems Summary: UniSet - library for building distributed industrial control systems
License: LGPL-2.1 License: LGPL-2.1
...@@ -185,6 +185,7 @@ Obsoletes: %name-extentions-devel ...@@ -185,6 +185,7 @@ Obsoletes: %name-extentions-devel
%description extension-common-devel %description extension-common-devel
Libraries needed to develop for uniset extensions Libraries needed to develop for uniset extensions
%if_enabled api
%if_enabled uresolver %if_enabled uresolver
%package extension-uresolver %package extension-uresolver
Group: Development/Tools Group: Development/Tools
...@@ -193,6 +194,16 @@ Summary: CORBA object reference resolver based on http ...@@ -193,6 +194,16 @@ Summary: CORBA object reference resolver based on http
%description extension-uresolver %description extension-uresolver
CORBA object reference resolver based on http CORBA object reference resolver based on http
%endif %endif
%endif
%if_enabled api
%package extension-wsgate
Group: Development/Tools
Summary: Websocket gate for uniset
%description extension-wsgate
Websocket gate for uniset
%endif
%if_enabled mysql %if_enabled mysql
%package extension-mysql %package extension-mysql
...@@ -537,6 +548,11 @@ rm -f %buildroot%_docdir/%oname/html/*.md5 ...@@ -537,6 +548,11 @@ rm -f %buildroot%_docdir/%oname/html/*.md5
%_bindir/%oname-httpresolver* %_bindir/%oname-httpresolver*
%endif %endif
%if_enabled api
%files extension-wsgate
%_bindir/%oname-wsgate*
%endif
%files extension-common-devel %files extension-common-devel
%dir %_includedir/%oname/extensions %dir %_includedir/%oname/extensions
%_includedir/%oname/extensions/*.* %_includedir/%oname/extensions/*.*
...@@ -560,7 +576,7 @@ rm -f %buildroot%_docdir/%oname/html/*.md5 ...@@ -560,7 +576,7 @@ rm -f %buildroot%_docdir/%oname/html/*.md5
# history of current unpublished changes # history of current unpublished changes
%changelog %changelog
* Fri Feb 12 2021 Pavel Vainerman <pv@altlinux.ru> 2.9.3-alt1.M90P.2 * Fri Mar 05 2021 Pavel Vainerman <pv@altlinux.ru> 2.9.4-alt0.M90P.0.1
- backport to ALTLinux p9 (by rpmbph script) - backport to ALTLinux p9 (by rpmbph script)
* Sun Jan 31 2021 Pavel Vainerman <pv@altlinux.ru> 2.9.3-alt2 * Sun Jan 31 2021 Pavel Vainerman <pv@altlinux.ru> 2.9.3-alt2
...@@ -569,6 +585,9 @@ rm -f %buildroot%_docdir/%oname/html/*.md5 ...@@ -569,6 +585,9 @@ rm -f %buildroot%_docdir/%oname/html/*.md5
* Thu Jan 14 2021 Pavel Vainerman <pv@altlinux.ru> 2.9.3-alt1 * Thu Jan 14 2021 Pavel Vainerman <pv@altlinux.ru> 2.9.3-alt1
- minor fixes (supported old omniORB) - minor fixes (supported old omniORB)
* Wed Jan 13 2021 Pavel Vainerman <pv@altlinux.ru> 2.9.3-alt0.1
- test build for websocketgate
* Sat Jan 09 2021 Pavel Vainerman <pv@altlinux.ru> 2.9.2-alt1 * Sat Jan 09 2021 Pavel Vainerman <pv@altlinux.ru> 2.9.2-alt1
- admin: added 'sinfo' function - admin: added 'sinfo' function
- admin: freezeValue -> freeze/unfreeze - admin: freezeValue -> freeze/unfreeze
......
...@@ -594,6 +594,10 @@ AC_CONFIG_FILES([Makefile ...@@ -594,6 +594,10 @@ AC_CONFIG_FILES([Makefile
extensions/HttpResolver/Makefile extensions/HttpResolver/Makefile
extensions/HttpResolver/tests/Makefile extensions/HttpResolver/tests/Makefile
extensions/UWebSocketGate/Makefile extensions/UWebSocketGate/Makefile
<<<<<<< HEAD
=======
extensions/UWebSocketGate/tests/Makefile
>>>>>>> 2.9.4-alt0.1
testsuite/Makefile testsuite/Makefile
wrappers/Makefile wrappers/Makefile
wrappers/python/lib/Makefile wrappers/python/lib/Makefile
......
...@@ -7,7 +7,11 @@ SUBDIRS = lib include SharedMemory SharedMemory/tests IOControl IOControl/tests ...@@ -7,7 +7,11 @@ SUBDIRS = lib include SharedMemory SharedMemory/tests IOControl IOControl/tests
ModbusMaster ModbusSlave SMViewer UniNetwork UNetUDP UNetUDP/tests \ ModbusMaster ModbusSlave SMViewer UniNetwork UNetUDP UNetUDP/tests \
DBServer-MySQL DBServer-SQLite DBServer-PostgreSQL MQTTPublisher \ DBServer-MySQL DBServer-SQLite DBServer-PostgreSQL MQTTPublisher \
RRDServer tests ModbusMaster/tests ModbusSlave/tests LogDB LogDB/tests \ RRDServer tests ModbusMaster/tests ModbusSlave/tests LogDB LogDB/tests \
<<<<<<< HEAD
Backend-OpenTSDB HttpResolver HttpResolver/tests UWebSocketGate Backend-OpenTSDB HttpResolver HttpResolver/tests UWebSocketGate
=======
Backend-OpenTSDB HttpResolver HttpResolver/tests UWebSocketGate UWebSocketGate/tests
>>>>>>> 2.9.4-alt0.1
pkgconfigdir = $(libdir)/pkgconfig pkgconfigdir = $(libdir)/pkgconfig
......
<<<<<<< HEAD
=======
if ENABLE_REST_API
>>>>>>> 2.9.4-alt0.1
bin_PROGRAMS = @PACKAGE@-wsgate bin_PROGRAMS = @PACKAGE@-wsgate
@PACKAGE@_wsgate_LDADD = $(top_builddir)/lib/libUniSet2.la @PACKAGE@_wsgate_LDADD = $(top_builddir)/lib/libUniSet2.la
@PACKAGE@_wsgate_SOURCES = UWebSocketGate.cc main.cc @PACKAGE@_wsgate_SOURCES = UWebSocketGate.cc main.cc
include $(top_builddir)/include.mk include $(top_builddir)/include.mk
<<<<<<< HEAD
=======
endif
>>>>>>> 2.9.4-alt0.1
...@@ -66,6 +66,7 @@ UWebSocketGate::UWebSocketGate( uniset::ObjectId id, xmlNode* cnode, const strin ...@@ -66,6 +66,7 @@ UWebSocketGate::UWebSocketGate( uniset::ObjectId id, xmlNode* cnode, const strin
sigINT.set<UWebSocketGate, &UWebSocketGate::onTerminate>(this); sigINT.set<UWebSocketGate, &UWebSocketGate::onTerminate>(this);
iocheck.set<UWebSocketGate, &UWebSocketGate::checkMessages>(this); iocheck.set<UWebSocketGate, &UWebSocketGate::checkMessages>(this);
<<<<<<< HEAD
#ifndef DISABLE_REST_API #ifndef DISABLE_REST_API
wsHeartbeatTime_sec = (float)conf->getArgPInt("--" + prefix + "ws-heartbeat-time", it.getProp("wsPingTime"), wsHeartbeatTime_sec) / 1000.0; wsHeartbeatTime_sec = (float)conf->getArgPInt("--" + prefix + "ws-heartbeat-time", it.getProp("wsPingTime"), wsHeartbeatTime_sec) / 1000.0;
wsSendTime_sec = (float)conf->getArgPInt("--" + prefix + "ws-send-time", it.getProp("wsSendTime"), wsSendTime_sec) / 1000.0; wsSendTime_sec = (float)conf->getArgPInt("--" + prefix + "ws-send-time", it.getProp("wsSendTime"), wsSendTime_sec) / 1000.0;
...@@ -73,6 +74,27 @@ UWebSocketGate::UWebSocketGate( uniset::ObjectId id, xmlNode* cnode, const strin ...@@ -73,6 +74,27 @@ UWebSocketGate::UWebSocketGate( uniset::ObjectId id, xmlNode* cnode, const strin
httpHost = conf->getArgParam("--" + prefix + "httpserver-host", "localhost"); httpHost = conf->getArgParam("--" + prefix + "httpserver-host", "localhost");
httpPort = conf->getArgPInt("--" + prefix + "httpserver-port", 8080); httpPort = conf->getArgPInt("--" + prefix + "httpserver-port", 8080);
=======
maxMessagesProcessing = conf->getArgPInt("--" + prefix + "max-messages-processing", conf->getField("maxMessagesProcessing"), maxMessagesProcessing);
if( maxMessagesProcessing < 0 )
maxMessagesProcessing = 100;
check_sec = (float)conf->getArgPInt("--" + prefix + "msg-check-time", it.getProp("msgCheckTime"), int(check_sec * 1000.0)) / 1000.0;
int sz = conf->getArgPInt("--uniset-object-size-message-queue", conf->getField("SizeOfMessageQueue"), 10000);
if( sz > 0 )
setMaxSizeOfMessageQueue(sz);
#ifndef DISABLE_REST_API
wsHeartbeatTime_sec = (float)conf->getArgPInt("--" + prefix + "ws-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;
wsMaxSend = conf->getArgPInt("--" + prefix + "ws-max-send", it.getProp("wsMaxSend"), wsMaxSend);
wsMaxCmd = conf->getArgPInt("--" + prefix + "ws-max-cmd", it.getProp("wsMaxCmd"), wsMaxCmd);
httpHost = conf->getArgParam("--" + prefix + "httpserver-host", "localhost");
httpPort = conf->getArgPInt("--" + prefix + "httpserver-port", 8081);
>>>>>>> 2.9.4-alt0.1
httpCORS_allow = conf->getArgParam("--" + prefix + "httpserver-cors-allow", "*"); httpCORS_allow = conf->getArgParam("--" + prefix + "httpserver-cors-allow", "*");
mylog1 << myname << "(init): http server parameters " << httpHost << ":" << httpPort << endl; mylog1 << myname << "(init): http server parameters " << httpHost << ":" << httpPort << endl;
...@@ -146,20 +168,38 @@ void UWebSocketGate::checkMessages( ev::timer& t, int revents ) ...@@ -146,20 +168,38 @@ void UWebSocketGate::checkMessages( ev::timer& t, int revents )
if( EV_ERROR & revents ) if( EV_ERROR & revents )
return; return;
<<<<<<< HEAD
auto m = receiveMessage(); auto m = receiveMessage();
if( m ) if( m )
processingMessage(m.get()); processingMessage(m.get());
=======
for( int i = 0; i < maxMessagesProcessing; i++ )
{
auto m = receiveMessage();
if( !m )
break;
processingMessage(m.get());
}
>>>>>>> 2.9.4-alt0.1
} }
//-------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------
void UWebSocketGate::sensorInfo( const SensorMessage* sm ) void UWebSocketGate::sensorInfo( const SensorMessage* sm )
{ {
uniset_rwmutex_wrlock lock(wsocksMutex); uniset_rwmutex_wrlock lock(wsocksMutex);
<<<<<<< HEAD
=======
mylog5 << myname << "(sensorInfo): sid=" << sm->id << " val=" << sm->value << endl;
>>>>>>> 2.9.4-alt0.1
for( auto&& s : wsocks ) for( auto&& s : wsocks )
s->sensorInfo(sm); s->sensorInfo(sm);
} }
//-------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------
<<<<<<< HEAD
UWebSocketGate::RespondFormat UWebSocketGate::from_string(const string& str) UWebSocketGate::RespondFormat UWebSocketGate::from_string(const string& str)
{ {
if( str == "json" ) if( str == "json" )
...@@ -192,13 +232,34 @@ UTCPCore::Buffer* UWebSocketGate::to_json( const SensorMessage* sm, const std::s ...@@ -192,13 +232,34 @@ UTCPCore::Buffer* UWebSocketGate::to_json( const SensorMessage* sm, const std::s
{ {
Poco::JSON::Object::Ptr json = new Poco::JSON::Object(); Poco::JSON::Object::Ptr json = new Poco::JSON::Object();
=======
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();
json->set("type", "SensorInfo");
>>>>>>> 2.9.4-alt0.1
json->set("error", err); json->set("error", err);
json->set("id", sm->id); json->set("id", sm->id);
json->set("value", sm->value); json->set("value", sm->value);
json->set("name", uniset::ORepHelpers::getShortName(uniset_conf()->oind->getMapName(sm->id))); json->set("name", uniset::ORepHelpers::getShortName(uniset_conf()->oind->getMapName(sm->id)));
json->set("sm_tv_sec", sm->sm_tv.tv_sec); json->set("sm_tv_sec", sm->sm_tv.tv_sec);
json->set("sm_tv_nsec", sm->sm_tv.tv_nsec); json->set("sm_tv_nsec", sm->sm_tv.tv_nsec);
<<<<<<< HEAD
json->set("type", uniset::iotype2str(sm->sensor_type)); json->set("type", uniset::iotype2str(sm->sensor_type));
=======
json->set("iotype", uniset::iotype2str(sm->sensor_type));
>>>>>>> 2.9.4-alt0.1
json->set("undefined", sm->undefined ); json->set("undefined", sm->undefined );
json->set("supplier", sm->supplier ); json->set("supplier", sm->supplier );
json->set("tv_sec", sm->tm.tv_sec); json->set("tv_sec", sm->tm.tv_sec);
...@@ -212,6 +273,7 @@ UTCPCore::Buffer* UWebSocketGate::to_json( const SensorMessage* sm, const std::s ...@@ -212,6 +273,7 @@ UTCPCore::Buffer* UWebSocketGate::to_json( const SensorMessage* sm, const std::s
calibr->set("rmax", sm->ci.maxRaw); calibr->set("rmax", sm->ci.maxRaw);
calibr->set("precision", sm->ci.precision); calibr->set("precision", sm->ci.precision);
<<<<<<< HEAD
ostringstream out; ostringstream out;
json->stringify(out); json->stringify(out);
return new UTCPCore::Buffer(out.str()); return new UTCPCore::Buffer(out.str());
...@@ -238,6 +300,9 @@ UTCPCore::Buffer* UWebSocketGate::to_txt( const SensorMessage* sm, const std::st ...@@ -238,6 +300,9 @@ UTCPCore::Buffer* UWebSocketGate::to_txt( const SensorMessage* sm, const std::st
UTCPCore::Buffer* UWebSocketGate::to_raw( const SensorMessage* sm, const std::string& err ) UTCPCore::Buffer* UWebSocketGate::to_raw( const SensorMessage* sm, const std::string& err )
{ {
return new UTCPCore::Buffer( (const unsigned char*)(sm), sizeof(*sm) ); return new UTCPCore::Buffer( (const unsigned char*)(sm), sizeof(*sm) );
=======
return json;
>>>>>>> 2.9.4-alt0.1
} }
//-------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------
std::shared_ptr<UWebSocketGate> UWebSocketGate::init_wsgate( int argc, const char* const* argv, const std::string& prefix ) std::shared_ptr<UWebSocketGate> UWebSocketGate::init_wsgate( int argc, const char* const* argv, const std::string& prefix )
...@@ -256,13 +321,30 @@ std::shared_ptr<UWebSocketGate> UWebSocketGate::init_wsgate( int argc, const cha ...@@ -256,13 +321,30 @@ std::shared_ptr<UWebSocketGate> UWebSocketGate::init_wsgate( int argc, const cha
void UWebSocketGate::help_print() void UWebSocketGate::help_print()
{ {
cout << "Default: prefix='ws'" << endl; cout << "Default: prefix='ws'" << endl;
<<<<<<< HEAD
cout << "--prefix-name name - Имя. Для поиска настроечной секции в configure.xml" << endl; cout << "--prefix-name name - Имя. Для поиска настроечной секции в configure.xml" << endl;
=======
cout << "--prefix-name name - Имя. Для поиска настроечной секции в configure.xml" << endl;
cout << "--uniset-object-size-message-queue num - Размер uniset-очереди сообщений" << endl;
cout << "--prefix-msg-check-time msec - Период опроса uniset-очереди сообщений, для обработки новых сообщений. По умолчанию: 10 мсек" << endl;
cout << "--prefix-max-messages-processing num - Количество uniset-сообщений обрабатывамых за один раз. По умолчанию 50. По умолчанию: 100" << endl;
>>>>>>> 2.9.4-alt0.1
cout << "websockets: " << endl; cout << "websockets: " << endl;
cout << "--prefix-ws-max num - Максимальное количество websocket-ов" << endl; cout << "--prefix-ws-max num - Максимальное количество websocket-ов" << endl;
cout << "--prefix-ws-heartbeat-time msec - Период сердцебиения в соединении. По умолчанию: 3000 мсек" << endl; cout << "--prefix-ws-heartbeat-time msec - Период сердцебиения в соединении. По умолчанию: 3000 мсек" << endl;
cout << "--prefix-ws-send-time msec - Период посылки сообщений. По умолчанию: 500 мсек" << endl; cout << "--prefix-ws-send-time msec - Период посылки сообщений. По умолчанию: 500 мсек" << endl;
cout << "--prefix-ws-max num - Максимальное число сообщений посылаемых за один раз. По умолчанию: 200" << endl; cout << "--prefix-ws-max num - Максимальное число сообщений посылаемых за один раз. По умолчанию: 200" << endl;
<<<<<<< HEAD
cout << "http: " << endl;
cout << "--prefix-httpserver-host ip - IP на котором слушает http сервер. По умолчанию: localhost" << endl;
cout << "--prefix-httpserver-port num - Порт на котором принимать запросы. По умолчанию: 8080" << endl;
cout << "--prefix-httpserver-max-queued num - Размер очереди запросов к http серверу. По умолчанию: 100" << endl;
cout << "--prefix-httpserver-max-threads num - Разрешённое количество потоков для http-сервера. По умолчанию: 3" << endl;
cout << "--prefix-httpserver-cors-allow addr - (CORS): Access-Control-Allow-Origin. Default: *" << endl;
=======
cout << "--prefix-ws-cmd num - Максимальное число команд обрабатываемых за один раз. По умолчанию: 100" << 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;
...@@ -270,6 +352,7 @@ void UWebSocketGate::help_print() ...@@ -270,6 +352,7 @@ void UWebSocketGate::help_print()
cout << "--prefix-httpserver-max-queued num - Размер очереди запросов к http серверу. По умолчанию: 100" << endl; cout << "--prefix-httpserver-max-queued num - Размер очереди запросов к http серверу. По умолчанию: 100" << endl;
cout << "--prefix-httpserver-max-threads num - Разрешённое количество потоков для http-сервера. По умолчанию: 3" << endl; cout << "--prefix-httpserver-max-threads num - Разрешённое количество потоков для http-сервера. По умолчанию: 3" << endl;
cout << "--prefix-httpserver-cors-allow addr - (CORS): Access-Control-Allow-Origin. Default: *" << endl; cout << "--prefix-httpserver-cors-allow addr - (CORS): Access-Control-Allow-Origin. Default: *" << endl;
>>>>>>> 2.9.4-alt0.1
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void UWebSocketGate::run( bool async ) void UWebSocketGate::run( bool async )
...@@ -426,6 +509,7 @@ void UWebSocketGate::handleRequest( Poco::Net::HTTPServerRequest& req, Poco::Net ...@@ -426,6 +509,7 @@ void UWebSocketGate::handleRequest( Poco::Net::HTTPServerRequest& req, Poco::Net
// проверка подключения к страничке со списком websocket-ов // проверка подключения к страничке со списком websocket-ов
if( !seg.empty() && seg[0] == "wsgate" ) if( !seg.empty() && seg[0] == "wsgate" )
{ {
<<<<<<< HEAD
if( seg.size() > 2 ) if( seg.size() > 2 )
{ {
if( seg[1] == "json" || seg[1] == "txt" || seg[1] == "raw" ) if( seg[1] == "json" || seg[1] == "txt" || seg[1] == "raw" )
...@@ -469,11 +553,37 @@ void UWebSocketGate::handleRequest( Poco::Net::HTTPServerRequest& req, Poco::Net ...@@ -469,11 +553,37 @@ void UWebSocketGate::handleRequest( Poco::Net::HTTPServerRequest& req, Poco::Net
return; return;
} }
=======
ostringstream params;
auto qp = uri.getQueryParameters();
int i = 0;
for( const auto& p : qp )
{
if( i > 0 )
params << "&";
params << p.first;
if( !p.second.empty() )
params << "=" << p.second;
i++;
}
httpWebSocketConnectPage(out, req, resp, params.str());
out.flush();
return;
>>>>>>> 2.9.4-alt0.1
} }
// default page // default page
httpWebSocketPage(out, req, resp); httpWebSocketPage(out, req, resp);
<<<<<<< HEAD
=======
>>>>>>> 2.9.4-alt0.1
out.flush(); out.flush();
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
...@@ -508,7 +618,11 @@ void UWebSocketGate::onWebSocketSession(Poco::Net::HTTPServerRequest& req, Poco: ...@@ -508,7 +618,11 @@ void UWebSocketGate::onWebSocketSession(Poco::Net::HTTPServerRequest& req, Poco:
mylog3 << req.getHost() << ": WSOCKET: " << uri.getQuery() << endl; mylog3 << req.getHost() << ": WSOCKET: " << uri.getQuery() << endl;
<<<<<<< HEAD
// example: ws://host:port/wsgate/?s1,s2,s3,s4&format=[json,txt,raw] // example: ws://host:port/wsgate/?s1,s2,s3,s4&format=[json,txt,raw]
=======
// example: ws://host:port/wsgate/?s1,s2,s3,s4
>>>>>>> 2.9.4-alt0.1
if( seg.empty() || seg[0] != "wsgate" ) if( seg.empty() || seg[0] != "wsgate" )
{ {
resp.setStatus(HTTPResponse::HTTP_BAD_REQUEST); resp.setStatus(HTTPResponse::HTTP_BAD_REQUEST);
...@@ -516,7 +630,11 @@ void UWebSocketGate::onWebSocketSession(Poco::Net::HTTPServerRequest& req, Poco: ...@@ -516,7 +630,11 @@ void UWebSocketGate::onWebSocketSession(Poco::Net::HTTPServerRequest& req, Poco:
resp.setStatusAndReason(HTTPResponse::HTTP_BAD_REQUEST); resp.setStatusAndReason(HTTPResponse::HTTP_BAD_REQUEST);
resp.setContentLength(0); resp.setContentLength(0);
std::ostream& err = resp.send(); std::ostream& err = resp.send();
<<<<<<< HEAD
err << "Bad request. Must be: ws://host:port/wsgate/?s1,s2,s3,s4&format=[json,txt,raw]"; err << "Bad request. Must be: ws://host:port/wsgate/?s1,s2,s3,s4&format=[json,txt,raw]";
=======
err << "Bad request. Must be: ws://host:port/wsgate/?s1,s2,s3,s4";
>>>>>>> 2.9.4-alt0.1
err.flush(); err.flush();
return; return;
} }
...@@ -577,22 +695,30 @@ std::shared_ptr<UWebSocketGate::UWebSocket> UWebSocketGate::newWebSocket( Poco:: ...@@ -577,22 +695,30 @@ std::shared_ptr<UWebSocketGate::UWebSocket> UWebSocketGate::newWebSocket( Poco::
std::shared_ptr<UWebSocket> ws; std::shared_ptr<UWebSocket> ws;
<<<<<<< HEAD
RespondFormat fmt = RespondFormat::JSON; RespondFormat fmt = RespondFormat::JSON;
=======
>>>>>>> 2.9.4-alt0.1
std::string slist(""); std::string slist("");
for( const auto& p : qp ) for( const auto& p : qp )
{ {
<<<<<<< HEAD
// обрабатываем только первый встреченный параметр // обрабатываем только первый встреченный параметр
if( p.first == "format" ) if( p.first == "format" )
fmt = from_string(p.second); fmt = from_string(p.second);
else if( p.second.empty() && !p.first.empty() ) else if( p.second.empty() && !p.first.empty() )
=======
if( p.second.empty() && !p.first.empty() )
>>>>>>> 2.9.4-alt0.1
slist += ("," + p.first); slist += ("," + p.first);
} }
if( qp.size() == 1 && qp[0].first.empty() ) if( qp.size() == 1 && qp[0].first.empty() )
slist = qp[0].first; slist = qp[0].first;
<<<<<<< HEAD
// auto idlist = uniset::explode(slist); // auto idlist = uniset::explode(slist);
#warning DEBUG #warning DEBUG
auto idlist = uniset::explode("34,23,54"); auto idlist = uniset::explode("34,23,54");
...@@ -611,6 +737,24 @@ std::shared_ptr<UWebSocketGate::UWebSocket> UWebSocketGate::newWebSocket( Poco:: ...@@ -611,6 +737,24 @@ std::shared_ptr<UWebSocketGate::UWebSocket> UWebSocketGate::newWebSocket( Poco::
return nullptr; return nullptr;
} }
=======
auto idlist = uniset::explode(slist);
// if( idlist.empty() )
// {
// resp->setStatus(HTTPResponse::HTTP_BAD_REQUEST);
// resp->setContentType("text/html");
// resp->setStatusAndReason(HTTPResponse::HTTP_BAD_REQUEST);
// resp->setContentLength(0);
// std::ostream& err = resp->send();
// err << "Error: no list of sensors for '" << slist << "'. Use: http://host:port/wsgate/?s1,s2,s3";
// err.flush();
// mywarn << myname << "(newWebSocket): error: no list of sensors for '" << slist << "'" << endl;
// return nullptr;
// }
>>>>>>> 2.9.4-alt0.1
{ {
uniset_rwmutex_wrlock lock(wsocksMutex); uniset_rwmutex_wrlock lock(wsocksMutex);
...@@ -618,6 +762,7 @@ std::shared_ptr<UWebSocketGate::UWebSocket> UWebSocketGate::newWebSocket( Poco:: ...@@ -618,6 +762,7 @@ std::shared_ptr<UWebSocketGate::UWebSocket> UWebSocketGate::newWebSocket( Poco::
ws->setHearbeatTime(wsHeartbeatTime_sec); ws->setHearbeatTime(wsHeartbeatTime_sec);
ws->setSendPeriod(wsSendTime_sec); ws->setSendPeriod(wsSendTime_sec);
ws->setMaxSendCount(wsMaxSend); ws->setMaxSendCount(wsMaxSend);
<<<<<<< HEAD
ws->mylog = mylog; ws->mylog = mylog;
ws->setRespondFormat(fmt); ws->setRespondFormat(fmt);
...@@ -629,6 +774,15 @@ std::shared_ptr<UWebSocketGate::UWebSocket> UWebSocketGate::newWebSocket( Poco:: ...@@ -629,6 +774,15 @@ std::shared_ptr<UWebSocketGate::UWebSocket> UWebSocketGate::newWebSocket( Poco::
si.id = i; si.id = i;
si.cmd = "ask"; si.cmd = "ask";
ws->add(si); ws->add(si);
=======
ws->setMaxCmdCount(wsMaxCmd);
ws->mylog = mylog;
for( const auto& i : idlist.getList() )
{
mylog3 << myname << ": ask sid=" << i << endl;
ws->ask(i);
>>>>>>> 2.9.4-alt0.1
} }
wsocks.emplace_back(ws); wsocks.emplace_back(ws);
...@@ -655,7 +809,11 @@ void UWebSocketGate::delWebSocket(std::shared_ptr<UWebSocket>& ws ) ...@@ -655,7 +809,11 @@ void UWebSocketGate::delWebSocket(std::shared_ptr<UWebSocket>& ws )
} }
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
<<<<<<< HEAD
const std::string UWebSocketGate::UWebSocket::ping_str = { "." }; const std::string UWebSocketGate::UWebSocket::ping_str = { "." };
=======
const std::string UWebSocketGate::UWebSocket::ping_str = { "{\"data\": [{\"type\": \"Ping\"}]}" };
>>>>>>> 2.9.4-alt0.1
UWebSocketGate::UWebSocket::UWebSocket(Poco::Net::HTTPServerRequest* _req, UWebSocketGate::UWebSocket::UWebSocket(Poco::Net::HTTPServerRequest* _req,
Poco::Net::HTTPServerResponse* _resp): Poco::Net::HTTPServerResponse* _resp):
...@@ -716,10 +874,47 @@ void UWebSocketGate::UWebSocket::send( ev::timer& t, int revents ) ...@@ -716,10 +874,47 @@ void UWebSocketGate::UWebSocket::send( ev::timer& t, int revents )
if( EV_ERROR & revents ) if( EV_ERROR & revents )
return; return;
<<<<<<< HEAD
for( size_t i = 0; !wbuf.empty() && i < maxsend && !cancelled; i++ ) for( size_t i = 0; !wbuf.empty() && i < maxsend && !cancelled; i++ )
write(); write();
// read(iorecv,revents); // read(iorecv,revents);
=======
if( !jbuf.empty() )
{
// сперва формируем очередной пакет(поток байт) из накопившихся данных для отправки
ostringstream out;
out << "{\"data\":[";
size_t i = 0;
for( ; !jbuf.empty() && !cancelled; i++ )
{
if( i > 0 )
out << ",";
auto json = jbuf.front();
jbuf.pop();
if( !json )
continue;
json->stringify(out);
}
out << "]}";
wbuf.emplace( new UTCPCore::Buffer(std::move(out.str())) );
mylog4 << req->clientAddress().toString() << "(write): batch " << i << " objects" << endl;
}
// реальная посылка данных
for( size_t i = 0; !wbuf.empty() && i < maxsend && !cancelled; i++ )
{
write();
}
>>>>>>> 2.9.4-alt0.1
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void UWebSocketGate::UWebSocket::ping( ev::timer& t, int revents ) void UWebSocketGate::UWebSocket::ping( ev::timer& t, int revents )
...@@ -810,21 +1005,38 @@ void UWebSocketGate::UWebSocket::read( ev::io& io, int revents ) ...@@ -810,21 +1005,38 @@ void UWebSocketGate::UWebSocket::read( ev::io& io, int revents )
} }
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
<<<<<<< HEAD
void UWebSocketGate::UWebSocket::add( const sinfo& si ) void UWebSocketGate::UWebSocket::add( const sinfo& si )
{ {
smap[si.id] = si; smap[si.id] = si;
=======
void UWebSocketGate::UWebSocket::ask( uniset::ObjectId id )
{
sinfo s;
s.id = id;
s.cmd = "ask";
qcmd.push(s);
>>>>>>> 2.9.4-alt0.1
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void UWebSocketGate::UWebSocket::del( uniset::ObjectId id ) void UWebSocketGate::UWebSocket::del( uniset::ObjectId id )
{ {
<<<<<<< HEAD
auto s = smap.find(id); auto s = smap.find(id);
if( s != smap.end() ) if( s != smap.end() )
s->second.cmd = "del"; s->second.cmd = "del";
=======
sinfo s;
s.id = id;
s.cmd = "del";
qcmd.push(s);
>>>>>>> 2.9.4-alt0.1
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void UWebSocketGate::UWebSocket::set( uniset::ObjectId id, long value ) void UWebSocketGate::UWebSocket::set( uniset::ObjectId id, long value )
{ {
<<<<<<< HEAD
auto s = smap.find(id); auto s = smap.find(id);
if( s != smap.end() ) if( s != smap.end() )
...@@ -832,6 +1044,21 @@ void UWebSocketGate::UWebSocket::set( uniset::ObjectId id, long value ) ...@@ -832,6 +1044,21 @@ void UWebSocketGate::UWebSocket::set( uniset::ObjectId id, long value )
s->second.value = value; s->second.value = value;
s->second.cmd = "set"; s->second.cmd = "set";
} }
=======
sinfo s;
s.id = id;
s.value = value;
s.cmd = "set";
qcmd.push(s);
}
// -----------------------------------------------------------------------------
void UWebSocketGate::UWebSocket::get( uniset::ObjectId id )
{
sinfo s;
s.id = id;
s.cmd = "get";
qcmd.push(s);
>>>>>>> 2.9.4-alt0.1
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void UWebSocketGate::UWebSocket::sensorInfo( const uniset::SensorMessage* sm ) void UWebSocketGate::UWebSocket::sensorInfo( const uniset::SensorMessage* sm )
...@@ -844,13 +1071,21 @@ void UWebSocketGate::UWebSocket::sensorInfo( const uniset::SensorMessage* sm ) ...@@ -844,13 +1071,21 @@ void UWebSocketGate::UWebSocket::sensorInfo( const uniset::SensorMessage* sm )
if( s == smap.end() ) if( s == smap.end() )
return; return;
<<<<<<< HEAD
if( wbuf.size() > maxsize ) if( wbuf.size() > maxsize )
=======
if( jbuf.size() > maxsize )
>>>>>>> 2.9.4-alt0.1
{ {
mywarn << req->clientAddress().toString() << " lost messages..." << endl; mywarn << req->clientAddress().toString() << " lost messages..." << endl;
return; return;
} }
<<<<<<< HEAD
wbuf.emplace(UWebSocketGate::format(sm, s->second.err, fmt)); wbuf.emplace(UWebSocketGate::format(sm, s->second.err, fmt));
=======
jbuf.emplace(UWebSocketGate::to_json(sm, s->second.err));
>>>>>>> 2.9.4-alt0.1
if( ioping.is_active() ) if( ioping.is_active() )
ioping.stop(); ioping.stop();
...@@ -858,21 +1093,59 @@ void UWebSocketGate::UWebSocket::sensorInfo( const uniset::SensorMessage* sm ) ...@@ -858,21 +1093,59 @@ 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 )
{ {
<<<<<<< HEAD
for( auto&& io : smap ) for( auto&& io : smap )
{ {
auto& s = io.second; auto& s = io.second;
=======
for( size_t i = 0; i < maxcmd && !qcmd.empty(); i++ )
{
auto s = qcmd.front();
qcmd.pop();
>>>>>>> 2.9.4-alt0.1
try try
{ {
if( s.cmd == "" ) if( s.cmd == "" )
continue; continue;
<<<<<<< HEAD
if( s.cmd == "ask" ) if( s.cmd == "ask" )
ui->askSensor(s.id, UniversalIO::UIONotify); ui->askSensor(s.id, UniversalIO::UIONotify);
else if( s.cmd == "del" ) else if( s.cmd == "del" )
ui->askSensor(s.id, UniversalIO::UIODontNotify); ui->askSensor(s.id, UniversalIO::UIODontNotify);
else if( s.cmd == "set" ) else if( s.cmd == "set" )
ui->setValue(s.id, s.value); ui->setValue(s.id, s.value);
=======
mylog3 << req->clientAddress().toString() << "(doCommand): "
<< s.cmd << " sid=" << s.id
<< " value=" << s.value
<< endl;
if( s.cmd == "ask" )
{
ui->askSensor(s.id, UniversalIO::UIONotify);
smap[s.id] = s;
}
else if( s.cmd == "del" )
{
ui->askSensor(s.id, UniversalIO::UIODontNotify);
auto it = smap.find(s.id);
if( it != smap.end() )
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);
}
>>>>>>> 2.9.4-alt0.1
s.err = ""; s.err = "";
s.cmd = ""; s.cmd = "";
...@@ -880,17 +1153,53 @@ void UWebSocketGate::UWebSocket::doCommand( const std::shared_ptr<UInterface>& u ...@@ -880,17 +1153,53 @@ void UWebSocketGate::UWebSocket::doCommand( const std::shared_ptr<UInterface>& u
catch( std::exception& ex ) catch( std::exception& ex )
{ {
mycrit << "(UWebSocket::doCommand): " << ex.what() << endl; mycrit << "(UWebSocket::doCommand): " << ex.what() << endl;
<<<<<<< HEAD
sendError(s, ex.what()); sendError(s, ex.what());
=======
s.err = ex.what();
sendResponse(s);
>>>>>>> 2.9.4-alt0.1
} }
} }
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
<<<<<<< HEAD
void UWebSocketGate::UWebSocket::sendError( sinfo& si, const std::string& err ) void UWebSocketGate::UWebSocket::sendError( sinfo& si, const std::string& err )
{ {
uniset::SensorMessage sm(si.id, 0); uniset::SensorMessage sm(si.id, 0);
// sm.undefined = true; // sm.undefined = true;
si.err = err; si.err = err;
sensorInfo(&sm); sensorInfo(&sm);
=======
void UWebSocketGate::UWebSocket::sendShortResponse( sinfo& si )
{
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 )
{
mywarn << req->clientAddress().toString() << " lost messages..." << endl;
return;
}
jbuf.emplace(UWebSocketGate::to_json(&sm, si.err));
if( ioping.is_active() )
ioping.stop();
>>>>>>> 2.9.4-alt0.1
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void UWebSocketGate::UWebSocket::onCommand( const string& cmdtxt ) void UWebSocketGate::UWebSocket::onCommand( const string& cmdtxt )
...@@ -911,6 +1220,10 @@ void UWebSocketGate::UWebSocket::onCommand( const string& cmdtxt ) ...@@ -911,6 +1220,10 @@ void UWebSocketGate::UWebSocket::onCommand( const string& cmdtxt )
for( const auto& i : idlist ) for( const auto& i : idlist )
set(i.si.id, i.val); set(i.si.id, i.val);
<<<<<<< HEAD
=======
// уведомление о новой команде
>>>>>>> 2.9.4-alt0.1
cmdsignal->send(); cmdsignal->send();
} }
else if( cmd == "ask" ) else if( cmd == "ask" )
...@@ -921,6 +1234,7 @@ void UWebSocketGate::UWebSocket::onCommand( const string& cmdtxt ) ...@@ -921,6 +1234,7 @@ void UWebSocketGate::UWebSocket::onCommand( const string& cmdtxt )
auto idlist = uniset::explode(params); auto idlist = uniset::explode(params);
for( const auto& id : idlist.getList() ) for( const auto& id : idlist.getList() )
<<<<<<< HEAD
{ {
sinfo s; sinfo s;
s.id = id; s.id = id;
...@@ -929,6 +1243,11 @@ void UWebSocketGate::UWebSocket::onCommand( const string& cmdtxt ) ...@@ -929,6 +1243,11 @@ void UWebSocketGate::UWebSocket::onCommand( const string& cmdtxt )
} }
// даём команду на перезаказ датчиков // даём команду на перезаказ датчиков
=======
ask(id);
// уведомление о новой команде
>>>>>>> 2.9.4-alt0.1
cmdsignal->send(); cmdsignal->send();
} }
else if( cmd == "del" ) else if( cmd == "del" )
...@@ -941,7 +1260,24 @@ void UWebSocketGate::UWebSocket::onCommand( const string& cmdtxt ) ...@@ -941,7 +1260,24 @@ void UWebSocketGate::UWebSocket::onCommand( const string& cmdtxt )
for( const auto& id : idlist.getList() ) for( const auto& id : idlist.getList() )
del(id); del(id);
<<<<<<< HEAD
// даём команду на перезаказ датчиков // даём команду на перезаказ датчиков
=======
// уведомление о новой команде
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);
// уведомление о новой команде
>>>>>>> 2.9.4-alt0.1
cmdsignal->send(); cmdsignal->send();
} }
} }
...@@ -970,7 +1306,11 @@ void UWebSocketGate::UWebSocket::write() ...@@ -970,7 +1306,11 @@ void UWebSocketGate::UWebSocket::write()
int flags = WebSocket::FRAME_TEXT; int flags = WebSocket::FRAME_TEXT;
<<<<<<< HEAD
if( msg->len == 1 ) // это пинг состоящий из "." if( msg->len == 1 ) // это пинг состоящий из "."
=======
if( msg->len == ping_str.size() )
>>>>>>> 2.9.4-alt0.1
flags = WebSocket::FRAME_FLAG_FIN | WebSocket::FRAME_OP_PING; flags = WebSocket::FRAME_FLAG_FIN | WebSocket::FRAME_OP_PING;
try try
...@@ -1089,9 +1429,16 @@ void UWebSocketGate::UWebSocket::setMaxSendCount( size_t val ) ...@@ -1089,9 +1429,16 @@ void UWebSocketGate::UWebSocket::setMaxSendCount( size_t val )
maxsend = val; maxsend = val;
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
<<<<<<< HEAD
void UWebSocketGate::UWebSocket::setRespondFormat( UWebSocketGate::RespondFormat f ) void UWebSocketGate::UWebSocket::setRespondFormat( UWebSocketGate::RespondFormat f )
{ {
fmt = f; fmt = f;
=======
void UWebSocketGate::UWebSocket::setMaxCmdCount( size_t val )
{
if( val > 0 )
maxcmd = val;
>>>>>>> 2.9.4-alt0.1
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void UWebSocketGate::httpWebSocketPage( std::ostream& ostr, Poco::Net::HTTPServerRequest& req, Poco::Net::HTTPServerResponse& resp ) void UWebSocketGate::httpWebSocketPage( std::ostream& ostr, Poco::Net::HTTPServerRequest& req, Poco::Net::HTTPServerResponse& resp )
...@@ -1113,12 +1460,16 @@ void UWebSocketGate::httpWebSocketPage( std::ostream& ostr, Poco::Net::HTTPServe ...@@ -1113,12 +1460,16 @@ void UWebSocketGate::httpWebSocketPage( std::ostream& ostr, Poco::Net::HTTPServe
ostr << " <li><a target='_blank' href=\"http://" ostr << " <li><a target='_blank' href=\"http://"
<< req.serverAddress().toString() << req.serverAddress().toString()
<<<<<<< HEAD
<< "/wsgate/json\">42,30,1042 [json]</a></li>" << "/wsgate/json\">42,30,1042 [json]</a></li>"
<< endl; << endl;
ostr << " <li><a target='_blank' href=\"http://" ostr << " <li><a target='_blank' href=\"http://"
<< req.serverAddress().toString() << req.serverAddress().toString()
<< "/wsgate/txt\">42,30,1042 [txt]</a></li>" << "/wsgate/txt\">42,30,1042 [txt]</a></li>"
=======
<< "/wsgate/?42,30,1042\">42,30,1042</a></li>"
>>>>>>> 2.9.4-alt0.1
<< endl; << endl;
ostr << "</ul>" << endl; ostr << "</ul>" << endl;
...@@ -1162,7 +1513,11 @@ void UWebSocketGate::httpWebSocketConnectPage( ostream& ostr, ...@@ -1162,7 +1513,11 @@ void UWebSocketGate::httpWebSocketConnectPage( ostream& ostr,
ostr << "{" << endl; ostr << "{" << endl;
ostr << " if (\"WebSocket\" in window)" << endl; ostr << " if (\"WebSocket\" in window)" << endl;
ostr << " {" << endl; ostr << " {" << endl;
<<<<<<< HEAD
ostr << " var ws = new WebSocket(\"ws://" << req.serverAddress().toString() << "/wsgate/\");" << endl; ostr << " var ws = new WebSocket(\"ws://" << req.serverAddress().toString() << "/wsgate/\");" << endl;
=======
ostr << " var ws = new WebSocket(\"ws://" << req.serverAddress().toString() << "/wsgate/?" << params << "\");" << endl;
>>>>>>> 2.9.4-alt0.1
ostr << "setInterval(send_cmd, 1000);" << endl; ostr << "setInterval(send_cmd, 1000);" << endl;
ostr << " var l = document.getElementById('logname');" << endl; ostr << " var l = document.getElementById('logname');" << endl;
ostr << " l.innerHTML = '*'" << endl; ostr << " l.innerHTML = '*'" << endl;
...@@ -1189,7 +1544,11 @@ void UWebSocketGate::httpWebSocketConnectPage( ostream& ostr, ...@@ -1189,7 +1544,11 @@ void UWebSocketGate::httpWebSocketConnectPage( ostream& ostr,
ostr << " }" << endl; ostr << " }" << endl;
ostr << "function send_cmd() {" << endl; ostr << "function send_cmd() {" << endl;
<<<<<<< HEAD
ostr << " ws.send( 'set:12,32,34' );" << endl; ostr << " ws.send( 'set:12,32,34' );" << endl;
=======
// ostr << " ws.send( 'set:12,32,34' );" << endl;
>>>>>>> 2.9.4-alt0.1
ostr << "}" << endl; ostr << "}" << endl;
ostr << "}" << endl; ostr << "}" << endl;
......
...@@ -55,13 +55,21 @@ namespace uniset ...@@ -55,13 +55,21 @@ namespace uniset
об изменнии датчиков, а так же изменять состояние (см. \ref sec_UWebSocketGate_Command). об изменнии датчиков, а так же изменять состояние (см. \ref sec_UWebSocketGate_Command).
Подключение к websocket-у доступно по адресу: Подключение к websocket-у доступно по адресу:
\code \code
<<<<<<< HEAD
ws://host:port/wsgate/?s1,s2,s3,s4&format=[json,txt,raw] ws://host:port/wsgate/?s1,s2,s3,s4&format=[json,txt,raw]
=======
ws://host:port/wsgate/
>>>>>>> 2.9.4-alt0.1
\endcode \endcode
Помимо этого UWebSocketGate работает в режиме мониторинга изменений датчиков. Помимо этого UWebSocketGate работает в режиме мониторинга изменений датчиков.
Для этого достаточно зайти на страничку по адресу: Для этого достаточно зайти на страничку по адресу:
\code \code
<<<<<<< HEAD
http://host:port/wsgate/?s1,s2,s3,s4&format=[json,txt,raw] http://host:port/wsgate/?s1,s2,s3,s4&format=[json,txt,raw]
=======
http://host:port/wsgate/?s1,s2,s3,s4
>>>>>>> 2.9.4-alt0.1
\endcode \endcode
\section sec_UWebSocketGate_Conf Конфигурирование UWebSocketGate \section sec_UWebSocketGate_Conf Конфигурирование UWebSocketGate
...@@ -75,7 +83,93 @@ namespace uniset ...@@ -75,7 +83,93 @@ namespace uniset
\section sec_UWebSocketGate_DETAIL UWebSocketGate: Технические детали \section sec_UWebSocketGate_DETAIL UWebSocketGate: Технические детали
Вся релизация построена на "однопоточном" eventloop. Если датчики долго не меняются, то периодически посылается "ping" сообщение. Вся релизация построена на "однопоточном" eventloop. Если датчики долго не меняются, то периодически посылается "ping" сообщение.
<<<<<<< HEAD
\section sec_UWebSocketGate_Command Команды \section sec_UWebSocketGate_Command Команды
=======
\section sec_UWebSocketGate_Messages Сообщения
Общий формат сообщений
\code
{
"data": [
{
"type": "SensorInfo",
...
},
{
"type": "SensorInfo",
...
},
{
"type": "OtherType",
...
},
{
"type": "YetAnotherType",
...
},
]}
\endcode
Example
\code
{
"data": [
{
"type": "SensorInfo",
"tv_nsec": 343079769,
"tv_sec": 1614521238,
"value": 63
"sm_tv_nsec": 976745544,
"sm_tv_sec": 1614520060,
"sm_type": "AI",
"error": "",
"id": 10,
"name": "AI_AS",
"node": 3000,
"supplier": 5003,
"undefined": false,
"calibration": {
"cmax": 0,
"cmin": 0,
"precision": 3,
"rmax": 0,
"rmin": 0
},
}]
}
\endcode
\section sec_UWebSocketGate_Get Get
Функция get возвращает результат в укороченном формате
\code
{
"data": [
{
"type": "ShortSensorInfo",
"value": 63
"error": "",
"id": 10,
},
}]
}
\endcode
\section sec_UWebSocketGate_Ping Ping
Для того, чтобы соединение не закрывалось при отсутствии данных, каждые ping_sec посылается
специальное сообщение
\code
{
"data": [
{"type": "Ping"}
]
}
\endcode
По умолчанию каждый 3 секунды, но время можно задавать параметром "wsHeartbeatTime" (msec)
или аргументом командной строки
--prefix-ws-heartbeat-time msec
\section sec_UWebSocketGate_Command Команды
>>>>>>> 2.9.4-alt0.1
Через websocket можно посылать команды. Через websocket можно посылать команды.
На текущий момент формат команды строковый. На текущий момент формат команды строковый.
Т.е. для подачи команды, необходимо послать просто строку. Т.е. для подачи команды, необходимо послать просто строку.
...@@ -84,9 +178,13 @@ namespace uniset ...@@ -84,9 +178,13 @@ 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,..." - отказаться от уведомления об изменении датчиков
<<<<<<< HEAD
\todo Разобраться с "ping" сообщением для формата json.. \todo Разобраться с "ping" сообщением для формата json..
\todo Настройка check_sec из командной строки и configure.xml \todo Настройка check_sec из командной строки и configure.xml
=======
- "get:id1,id2,name3,..." - получить текущее значение датчиков (разовое сообщение ShortSensorInfo)
>>>>>>> 2.9.4-alt0.1
*/ */
class UWebSocketGate: class UWebSocketGate:
public UniSetObject, public UniSetObject,
...@@ -149,7 +247,12 @@ namespace uniset ...@@ -149,7 +247,12 @@ namespace uniset
void checkMessages( ev::timer& t, int revents ); void checkMessages( ev::timer& t, int revents );
virtual void sensorInfo( const uniset::SensorMessage* sm ) override; virtual void sensorInfo( const uniset::SensorMessage* sm ) override;
ev::timer iocheck; ev::timer iocheck;
<<<<<<< HEAD
double check_sec = { 0.3 }; double check_sec = { 0.3 };
=======
double check_sec = { 0.05 };
int maxMessagesProcessing = { 100 };
>>>>>>> 2.9.4-alt0.1
std::shared_ptr<DebugStream> mylog; std::shared_ptr<DebugStream> mylog;
...@@ -162,6 +265,7 @@ namespace uniset ...@@ -162,6 +265,7 @@ namespace uniset
double wsHeartbeatTime_sec = { 3.0 }; double wsHeartbeatTime_sec = { 3.0 };
double wsSendTime_sec = { 0.5 }; double wsSendTime_sec = { 0.5 };
size_t wsMaxSend = { 200 }; size_t wsMaxSend = { 200 };
<<<<<<< HEAD
enum class RespondFormat enum class RespondFormat
{ {
...@@ -177,6 +281,11 @@ namespace uniset ...@@ -177,6 +281,11 @@ namespace uniset
static UTCPCore::Buffer* to_json( const uniset::SensorMessage* sm, const std::string& err ); static UTCPCore::Buffer* to_json( const uniset::SensorMessage* sm, const std::string& err );
static UTCPCore::Buffer* to_txt( const uniset::SensorMessage* sm, const std::string& err ); static UTCPCore::Buffer* to_txt( const uniset::SensorMessage* sm, const std::string& err );
static UTCPCore::Buffer* to_raw( const uniset::SensorMessage* sm, const std::string& err ); static UTCPCore::Buffer* to_raw( const uniset::SensorMessage* sm, const std::string& err );
=======
size_t wsMaxCmd = { 100 };
static Poco::JSON::Object::Ptr to_json( const uniset::SensorMessage* sm, const std::string& err );
>>>>>>> 2.9.4-alt0.1
/*! класс реализует работу с websocket через eventloop /*! класс реализует работу с websocket через eventloop
* Из-за того, что поступление логов может быть достаточно быстрым * Из-за того, что поступление логов может быть достаточно быстрым
...@@ -209,11 +318,22 @@ namespace uniset ...@@ -209,11 +318,22 @@ namespace uniset
long value = { 0 }; // set value long value = { 0 }; // set value
}; };
<<<<<<< HEAD
void add( const sinfo& si ); void add( const sinfo& si );
void del( uniset::ObjectId id ); void del( uniset::ObjectId id );
void set( uniset::ObjectId id, long value ); void set( uniset::ObjectId id, long value );
void sensorInfo( const uniset::SensorMessage* sm ); void sensorInfo( const uniset::SensorMessage* sm );
void doCommand( const std::shared_ptr<UInterface>& ui ); void doCommand( const std::shared_ptr<UInterface>& ui );
=======
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 );
>>>>>>> 2.9.4-alt0.1
void term(); void term();
...@@ -223,19 +343,32 @@ namespace uniset ...@@ -223,19 +343,32 @@ namespace uniset
void setHearbeatTime( const double& sec ); void setHearbeatTime( const double& sec );
void setSendPeriod( const double& sec ); void setSendPeriod( const double& sec );
void setMaxSendCount( size_t val ); void setMaxSendCount( size_t val );
<<<<<<< HEAD
void setRespondFormat( RespondFormat f ); void setRespondFormat( RespondFormat f );
=======
void setMaxCmdCount( size_t val );
>>>>>>> 2.9.4-alt0.1
std::shared_ptr<DebugStream> mylog; std::shared_ptr<DebugStream> mylog;
protected: protected:
void write(); void write();
<<<<<<< HEAD
void sendError( sinfo& si, const std::string& err ); void sendError( sinfo& si, const std::string& err );
=======
void sendResponse( sinfo& si );
void sendShortResponse( sinfo& si );
>>>>>>> 2.9.4-alt0.1
void onCommand( const std::string& cmd ); void onCommand( const std::string& cmd );
ev::timer iosend; ev::timer iosend;
double send_sec = { 0.5 }; double send_sec = { 0.5 };
size_t maxsend = { 200 }; size_t maxsend = { 200 };
<<<<<<< HEAD
=======
size_t maxcmd = { 100 };
>>>>>>> 2.9.4-alt0.1
ev::timer ioping; ev::timer ioping;
double ping_sec = { 3.0 }; double ping_sec = { 3.0 };
...@@ -252,13 +385,25 @@ namespace uniset ...@@ -252,13 +385,25 @@ namespace uniset
std::atomic_bool cancelled = { false }; std::atomic_bool cancelled = { false };
std::unordered_map<uniset::ObjectId, sinfo> smap; std::unordered_map<uniset::ObjectId, sinfo> smap;
<<<<<<< HEAD
RespondFormat fmt = { RespondFormat::JSON }; RespondFormat fmt = { RespondFormat::JSON };
=======
std::queue<sinfo> qcmd; // очередь команд
>>>>>>> 2.9.4-alt0.1
Poco::Net::HTTPServerRequest* req; Poco::Net::HTTPServerRequest* req;
Poco::Net::HTTPServerResponse* resp; Poco::Net::HTTPServerResponse* resp;
<<<<<<< HEAD
// очередь данных на посылку.. // очередь данных на посылку..
std::queue<UTCPCore::Buffer*> wbuf; std::queue<UTCPCore::Buffer*> wbuf;
=======
// очередь json-на отправку
std::queue<Poco::JSON::Object::Ptr> jbuf;
// очередь данных на посылку..
std::queue<uniset::UTCPCore::Buffer*> wbuf;
>>>>>>> 2.9.4-alt0.1
size_t maxsize; // рассчитывается сходя из max_send (см. конструктор) size_t maxsize; // рассчитывается сходя из max_send (см. конструктор)
}; };
......
if HAVE_TESTS
noinst_PROGRAMS = tests-with-sm
tests_with_sm_SOURCES = tests_with_sm.cc test_uwebsocketgate.cc $(top_builddir)/extensions/UWebSocketGate/UWebSocketGate.cc
tests_with_sm_LDADD = $(top_builddir)/lib/libUniSet2.la $(top_builddir)/extensions/lib/libUniSet2Extensions.la \
$(top_builddir)/extensions/SharedMemory/libUniSet2SharedMemory.la \
$(SIGC_LIBS) $(POCO_LIBS)
tests_with_sm_CPPFLAGS = -I$(top_builddir)/include -I$(top_builddir)/extensions/include \
-I$(top_builddir)/extensions/UWebSocketGate \
-I$(top_builddir)/extensions/SharedMemory $(SIGC_CFLAGS) $(POCO_CFLAGS)
include $(top_builddir)/testsuite/testsuite-common.mk
check-local: atconfig package.m4 $(TESTSUITE) uwebsocketgate-tests.at
$(SHELL) $(TESTSUITE) $(TESTSUITEFLAGS)
clean-local:
rm -rf $(CLEANFILES)
rm -rf $(COVERAGE_REPORT_DIR)
include $(top_builddir)/include.mk
endif
#include <catch.hpp>
// -----------------------------------------------------------------------------
#include <time.h>
#include <limits>
#include <memory>
#include <iostream>
#include "Poco/Net/HTTPRequest.h"
#include "Poco/Net/HTTPResponse.h"
#include "Poco/Net/HTTPMessage.h"
#include "Poco/Net/WebSocket.h"
#include "Poco/Net/HTTPClientSession.h"
#include "Poco/JSON/Parser.h"
#include "UniSetTypes.h"
#include "UInterface.h"
// -----------------------------------------------------------------------------
using Poco::Net::HTTPClientSession;
using Poco::Net::HTTPRequest;
using Poco::Net::HTTPResponse;
using Poco::Net::HTTPMessage;
using Poco::Net::WebSocket;
using namespace std;
using namespace uniset;
// -----------------------------------------------------------------------------
static int port = 8081;
static string addr("127.0.0.1");
static std::shared_ptr<UInterface> ui;
// -----------------------------------------------------------------------------
static void InitTest()
{
auto conf = uniset_conf();
CHECK( conf != nullptr );
if( !ui )
{
ui = std::make_shared<UInterface>();
// UI понадобиться для проверки записанных в SM значений.
CHECK( ui->getObjectIndex() != nullptr );
CHECK( ui->getConf() == conf );
}
}
// -----------------------------------------------------------------------------
TEST_CASE("[UWebSocketGate]: set", "[uwebsocketgate]")
{
InitTest();
HTTPClientSession cs(addr, port);
HTTPRequest request(HTTPRequest::HTTP_GET, "/wsgate", HTTPRequest::HTTP_1_1);
HTTPResponse response;
WebSocket ws(cs, request, response);
std::string cmd("set:1=10,2=20,3=30");
ws.sendFrame(cmd.data(), (int)cmd.size());
msleep(50);
REQUIRE( ui->getValue(1) == 10 );
REQUIRE( ui->getValue(2) == 20 );
REQUIRE( ui->getValue(3) == 30 );
cmd = "set:1=11,2=21,3=31";
ws.sendFrame(cmd.data(), (int)cmd.size());
msleep(50);
REQUIRE( ui->getValue(1) == 11 );
REQUIRE( ui->getValue(2) == 21 );
REQUIRE( ui->getValue(3) == 31 );
}
// -----------------------------------------------------------------------------
TEST_CASE("[UWebSocketGate]: ask", "[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, 1);
ui->setValue(2, 42);
ui->setValue(3, 42);
std::string cmd("ask:1,2,3");
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() == 3);
for( int i = 0; i < 3; 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 )
{
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 );
}
// -----------------------------------------------------------------------------
TEST_CASE("[UWebSocketGate]: del", "[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, 1);
std::string cmd("ask:1");
ws.sendFrame(cmd.data(), (int)cmd.size());
char buffer[1024] = {};
int flags;
ws.receiveFrame(buffer, sizeof(buffer), flags);
REQUIRE(flags == WebSocket::FRAME_TEXT);
cmd = ("del:1");
ws.sendFrame(cmd.data(), (int)cmd.size());
msleep(100);
ui->setValue(1, 0);
memset(buffer, 0, sizeof(buffer));
ws.receiveFrame(buffer, sizeof(buffer), flags);
string str(buffer);
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 );
}
}
}
// -----------------------------------------------------------------------------
#define CATCH_CONFIG_RUNNER
#include <catch.hpp>
#include <string>
#include "Debug.h"
#include "UniSetActivator.h"
#include "PassiveTimer.h"
#include "SharedMemory.h"
#include "Extensions.h"
#include "UWebSocketGate.h"
// --------------------------------------------------------------------------
using namespace std;
using namespace uniset;
using namespace uniset::extensions;
// --------------------------------------------------------------------------
int main(int argc, const char* argv[] )
{
try
{
Catch::Session session;
if( argc > 1 && ( strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-h") == 0 ) )
{
cout << "--confile - Использовать указанный конф. файл. По умолчанию configure.xml" << endl;
SharedMemory::help_print(argc, argv);
cout << endl << endl << "--------------- CATCH HELP --------------" << endl;
session.showHelp("test_with_sm");
return 0;
}
int returnCode = session.applyCommandLine( argc, argv, Catch::Session::OnUnusedOptions::Ignore );
if( returnCode != 0 ) // Indicates a command line error
return returnCode;
auto conf = uniset_init(argc, argv);
bool apart = findArgParam("--apart", argc, argv) != -1;
auto shm = SharedMemory::init_smemory(argc, argv);
if( !shm )
return 1;
auto ws = UWebSocketGate::init_wsgate(argc, argv, "ws-");
if( !ws )
return 1;
auto act = UniSetActivator::Instance();
act->add(shm);
act->add(ws);
SystemMessage sm(SystemMessage::StartUp);
act->broadcast( sm.transport_msg() );
act->run(true);
int tout = 6000;
PassiveTimer pt(tout);
while( !pt.checkTime() && !act->exist() && !ws->exist() )
msleep(100);
if( !act->exist() )
{
cerr << "(tests_with_sm): SharedMemory not exist! (timeout=" << tout << ")" << endl;
return 1;
}
if( !ws->exist() )
{
cerr << "(tests_with_sm): UWebSocketGate not exist! (timeout=" << tout << ")" << endl;
return 1;
}
return session.run();
}
catch( const SystemError& err )
{
cerr << "(tests_with_sm): " << err << endl;
}
catch( const uniset::Exception& ex )
{
cerr << "(tests_with_sm): " << ex << endl;
}
catch( const std::exception& e )
{
cerr << "(tests_with_sm): " << e.what() << endl;
}
catch(...)
{
cerr << "(tests_with_sm): catch(...)" << endl;
}
return 1;
}
#!/bin/sh
# '--' - нужен для отделения аргументов catch, от наших..
cd ../../../Utilities/Admin/
./uniset2-start.sh -f ./create_links.sh
./uniset2-start.sh -f ./create
./uniset2-start.sh -f ./exist | grep -q UNISET_PLC/Controllers || exit 1
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-log-add-levels any
m4_include(package.m4)
AT_COLOR_TESTS
AT_INIT([UWebSocketGate tests])
m4_include(uwebsocketgate-tests.at)
../../../Utilities/scripts/uniset2-functions.sh
\ No newline at end of file
../../../Utilities/scripts/uniset2-start.sh
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<UNISETPLC xmlns:xi="http://www.w3.org/2001/XInclude">
<UserData/>
<!-- Общие(стартовые) параметры по UniSet -->
<UniSet>
<NameService host="localhost" port="2809"/>
<LocalNode name="LocalhostNode"/>
<RootSection name="UNISET_PLC"/>
<CountOfNet name="1"/>
<RepeatCount name="3"/>
<RepeatTimeoutMS name="50"/>
<WatchDogTime name="0"/>
<PingNodeTime name="0"/>
<AutoStartUpTime name="1"/>
<DumpStateTime name="10"/>
<SleepTickMS name="500"/>
<UniSetDebug levels="" name="ulog"/>
<ConfDir name="./"/>
<DataDir name="./"/>
<BinDir name="./"/>
<LogDir name="./"/>
<DocDir name="./"/>
<LockDir name="./"/>
<Services></Services>
</UniSet>
<dlog name="dlog"/>
<settings>
<SharedMemory name="SharedMemory" shmID="SharedMemory"/>
<UWebSocketGate name="UWebSocketGate1"/>
</settings>
<ObjectsMap idfromfile="1">
<!--
Краткие пояснения к полям секции 'sensors'
==========================================
node - узел на котором физически находится данный датчик
iotype - тип датчика
priority - приоритет сообщения об изменении данного датчика
textname - текстовое имя датчика
-->
<nodes port="2809">
<item id="3000" infserver="InfoServer" ip="127.0.0.1" name="LocalhostNode" textname="Локальный узел"/>
</nodes>
<!-- ************************ Датчики ********************** -->
<sensors name="Sensors">
<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="3" iotype="AI" name="AI2_S" textname="AI sensor 2" default="3"/>
</sensors>
<thresholds/>
<controllers name="Controllers">
<item id="5000" name="SharedMemory"/>
</controllers>
<!-- ******************* Идентификаторы сервисов ***************** -->
<services name="Services">
</services>
<!-- ******************* Идентификаторы объектов ***************** -->
<objects name="UniObjects">
<item id="6000" name="TestProc"/>
<item id="6004" name="UWebSocketGate1"/>
</objects>
</ObjectsMap>
<messages idfromfile="1" name="messages"/>
</UNISETPLC>
AT_SETUP([UWebSocketGate tests])
AT_CHECK([$abs_top_builddir/testsuite/at-test-launch.sh $abs_top_builddir/extensions/UWebSocketGate/tests tests_with_sm.sh],[0],[ignore],[ignore])
AT_CLEANUP
...@@ -14,3 +14,4 @@ m4_include(../extensions/LogicProcessor/tests/lproc-tests.at) ...@@ -14,3 +14,4 @@ m4_include(../extensions/LogicProcessor/tests/lproc-tests.at)
m4_include(../extensions/IOControl/tests/iocontrol-tests.at) m4_include(../extensions/IOControl/tests/iocontrol-tests.at)
m4_include(../extensions/LogDB/tests/logdb-tests.at) m4_include(../extensions/LogDB/tests/logdb-tests.at)
m4_include(../extensions/HttpResolver/tests/uresolver-tests.at) m4_include(../extensions/HttpResolver/tests/uresolver-tests.at)
m4_include(../extensions/UWebSocketGate/tests/uwebsocketgate-tests.at)
...@@ -297,6 +297,17 @@ ...@@ -297,6 +297,17 @@
./extensions/UniNetwork/uninet.cc ./extensions/UniNetwork/uninet.cc
./extensions/UWebSocketGate/main.cc ./extensions/UWebSocketGate/main.cc
./extensions/UWebSocketGate/Makefile.am ./extensions/UWebSocketGate/Makefile.am
<<<<<<< HEAD
=======
./extensions/UWebSocketGate.old/main.cc
./extensions/UWebSocketGate.old/Makefile.am
./extensions/UWebSocketGate.old/UWebSocketGate.cc
./extensions/UWebSocketGate.old/UWebSocketGate.h
./extensions/UWebSocketGate.old/UWebSocketGateSugar.h
./extensions/UWebSocketGate/tests/Makefile.am
./extensions/UWebSocketGate/tests/tests_with_sm.cc
./extensions/UWebSocketGate/tests/test_uwebsocketgate.cc
>>>>>>> 2.9.4-alt0.1
./extensions/UWebSocketGate/UWebSocketGate.cc ./extensions/UWebSocketGate/UWebSocketGate.cc
./extensions/UWebSocketGate/UWebSocketGate.h ./extensions/UWebSocketGate/UWebSocketGate.h
./extensions/UWebSocketGate/UWebSocketGateSugar.h ./extensions/UWebSocketGate/UWebSocketGateSugar.h
...@@ -390,7 +401,6 @@ ...@@ -390,7 +401,6 @@
./include/UTCPStream.h ./include/UTCPStream.h
./include/VMonitor.h ./include/VMonitor.h
./include/WDTInterface.h ./include/WDTInterface.h
./lib/dummy.cc
./lib/Makefile.am ./lib/Makefile.am
./Makefile.am ./Makefile.am
./src/Communications/ComPort485F.cc ./src/Communications/ComPort485F.cc
...@@ -555,6 +565,8 @@ ...@@ -555,6 +565,8 @@
./tests/umutex.cc ./tests/umutex.cc
./tests/UniXmlTest/Makefile.am ./tests/UniXmlTest/Makefile.am
./tests/UniXmlTest/XmlTest.cc ./tests/UniXmlTest/XmlTest.cc
./tests/wasm-test/main.cc
./tests/wasm-test/Makefile.am
./uniset-config.h ./uniset-config.h
./Utilities/Admin/admin.cc ./Utilities/Admin/admin.cc
./Utilities/Admin/c.cc ./Utilities/Admin/c.cc
......
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