Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
U
uniset2
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
1
Issues
1
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
UniSet project repositories
uniset2
Commits
36839d01
Commit
36839d01
authored
Mar 05, 2021
by
Pavel Vainerman
Browse files
Options
Browse Files
Download
Plain Diff
backported to p9 as 2.9.4-alt0.M90P.0.1 (with rpmbph script)
parents
c4d818e4
ddb69cc9
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
1018 additions
and
4 deletions
+1018
-4
libuniset2.spec
conf/libuniset2.spec
+22
-3
configure.ac
configure.ac
+4
-0
Makefile.am
extensions/Makefile.am
+4
-0
Makefile.am
extensions/UWebSocketGate/Makefile.am
+8
-0
UWebSocketGate.cc
extensions/UWebSocketGate/UWebSocketGate.cc
+359
-0
UWebSocketGate.h
extensions/UWebSocketGate/UWebSocketGate.h
+145
-0
Makefile.am
extensions/UWebSocketGate/tests/Makefile.am
+25
-0
test_uwebsocketgate.cc
extensions/UWebSocketGate/tests/test_uwebsocketgate.cc
+247
-0
tests_with_sm.cc
extensions/UWebSocketGate/tests/tests_with_sm.cc
+97
-0
tests_with_sm.sh
extensions/UWebSocketGate/tests/tests_with_sm.sh
+15
-0
testsuite.at
extensions/UWebSocketGate/tests/testsuite.at
+7
-0
uniset2-functions.sh
extensions/UWebSocketGate/tests/uniset2-functions.sh
+2
-0
uniset2-start.sh
extensions/UWebSocketGate/tests/uniset2-start.sh
+2
-0
uwebsocketgate-test-configure.xml
...ns/UWebSocketGate/tests/uwebsocketgate-test-configure.xml
+64
-0
uwebsocketgate-tests.at
extensions/UWebSocketGate/tests/uwebsocketgate-tests.at
+3
-0
testsuite.at
testsuite/testsuite.at
+1
-0
uniset2.files
uniset2.files
+13
-1
No files found.
conf/libuniset2.spec
View file @
36839d01
...
...
@@ -26,8 +26,8 @@
%define oname uniset2
Name: libuniset2
Version: 2.9.
3
Release: alt
1.M90P.2
Version: 2.9.
4
Release: alt
0.M90P.0.1
Summary: UniSet - library for building distributed industrial control systems
License: LGPL-2.1
...
...
@@ -185,6 +185,7 @@ Obsoletes: %name-extentions-devel
%description extension-common-devel
Libraries needed to develop for uniset extensions
%if_enabled api
%if_enabled uresolver
%package extension-uresolver
Group: Development/Tools
...
...
@@ -193,6 +194,16 @@ Summary: CORBA object reference resolver based on http
%description extension-uresolver
CORBA object reference resolver based on http
%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
%package extension-mysql
...
...
@@ -537,6 +548,11 @@ rm -f %buildroot%_docdir/%oname/html/*.md5
%_bindir/%oname-httpresolver*
%endif
%if_enabled api
%files extension-wsgate
%_bindir/%oname-wsgate*
%endif
%files extension-common-devel
%dir %_includedir/%oname/extensions
%_includedir/%oname/extensions/*.*
...
...
@@ -560,7 +576,7 @@ rm -f %buildroot%_docdir/%oname/html/*.md5
# history of current unpublished changes
%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)
* Sun Jan 31 2021 Pavel Vainerman <pv@altlinux.ru> 2.9.3-alt2
...
...
@@ -569,6 +585,9 @@ rm -f %buildroot%_docdir/%oname/html/*.md5
* Thu Jan 14 2021 Pavel Vainerman <pv@altlinux.ru> 2.9.3-alt1
- 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
- admin: added 'sinfo' function
- admin: freezeValue -> freeze/unfreeze
...
...
configure.ac
View file @
36839d01
...
...
@@ -594,6 +594,10 @@ AC_CONFIG_FILES([Makefile
extensions/HttpResolver/Makefile
extensions/HttpResolver/tests/Makefile
extensions/UWebSocketGate/Makefile
<<<<<<< HEAD
=======
extensions/UWebSocketGate/tests/Makefile
>>>>>>> 2.9.4-alt0.1
testsuite/Makefile
wrappers/Makefile
wrappers/python/lib/Makefile
...
...
extensions/Makefile.am
View file @
36839d01
...
...
@@ -7,7 +7,11 @@ SUBDIRS = lib include SharedMemory SharedMemory/tests IOControl IOControl/tests
ModbusMaster ModbusSlave SMViewer UniNetwork UNetUDP UNetUDP/tests
\
DBServer-MySQL DBServer-SQLite DBServer-PostgreSQL MQTTPublisher
\
RRDServer tests ModbusMaster/tests ModbusSlave/tests LogDB LogDB/tests
\
<<<<<<
< HEAD
Backend-OpenTSDB
HttpResolver
HttpResolver/tests
UWebSocketGate
=======
Backend-OpenTSDB
HttpResolver
HttpResolver/tests
UWebSocketGate
UWebSocketGate/tests
>>>>>>>
2.9.4-alt0.1
pkgconfigdir
=
$(libdir)
/pkgconfig
...
...
extensions/UWebSocketGate/Makefile.am
View file @
36839d01
<<<<<<<
HEAD
=======
if
ENABLE_REST_API
>>>>>>>
2.9.4-alt0.1
bin_PROGRAMS
=
@PACKAGE@-wsgate
@PACKAGE@
_wsgate_LDADD
=
$(top_builddir)
/lib/libUniSet2.la
@PACKAGE@
_wsgate_SOURCES
=
UWebSocketGate.cc main.cc
include
$(top_builddir)/include.mk
<<<<<<<
HEAD
=======
endif
>>>>>>>
2.9.4-alt0.1
extensions/UWebSocketGate/UWebSocketGate.cc
View file @
36839d01
...
...
@@ -66,6 +66,7 @@ UWebSocketGate::UWebSocketGate( uniset::ObjectId id, xmlNode* cnode, const strin
sigINT
.
set
<
UWebSocketGate
,
&
UWebSocketGate
::
onTerminate
>
(
this
);
iocheck
.
set
<
UWebSocketGate
,
&
UWebSocketGate
::
checkMessages
>
(
this
);
<<<<<<<
HEAD
#ifndef DISABLE_REST_API
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
;
...
...
@@ -73,6 +74,27 @@ UWebSocketGate::UWebSocketGate( uniset::ObjectId id, xmlNode* cnode, const strin
httpHost
=
conf
->
getArgParam
(
"--"
+
prefix
+
"httpserver-host"
,
"localhost"
);
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"
,
"*"
);
mylog1
<<
myname
<<
"(init): http server parameters "
<<
httpHost
<<
":"
<<
httpPort
<<
endl
;
...
...
@@ -146,20 +168,38 @@ void UWebSocketGate::checkMessages( ev::timer& t, int revents )
if
(
EV_ERROR
&
revents
)
return
;
<<<<<<<
HEAD
auto
m
=
receiveMessage
();
if
(
m
)
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
)
{
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
)
s
->
sensorInfo
(
sm
);
}
//--------------------------------------------------------------------------------------------
<<<<<<<
HEAD
UWebSocketGate
::
RespondFormat
UWebSocketGate
::
from_string
(
const
string
&
str
)
{
if
(
str
==
"json"
)
...
...
@@ -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
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
(
"id"
,
sm
->
id
);
json
->
set
(
"value"
,
sm
->
value
);
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_nsec"
,
sm
->
sm_tv
.
tv_nsec
);
<<<<<<<
HEAD
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
(
"supplier"
,
sm
->
supplier
);
json
->
set
(
"tv_sec"
,
sm
->
tm
.
tv_sec
);
...
...
@@ -212,6 +273,7 @@ UTCPCore::Buffer* UWebSocketGate::to_json( const SensorMessage* sm, const std::s
calibr
->
set
(
"rmax"
,
sm
->
ci
.
maxRaw
);
calibr
->
set
(
"precision"
,
sm
->
ci
.
precision
);
<<<<<<<
HEAD
ostringstream
out
;
json
->
stringify
(
out
);
return
new
UTCPCore
::
Buffer
(
out
.
str
());
...
...
@@ -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
)
{
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
)
...
...
@@ -256,13 +321,21 @@ std::shared_ptr<UWebSocketGate> UWebSocketGate::init_wsgate( int argc, const cha
void
UWebSocketGate
::
help_print
()
{
cout
<<
"Default: prefix='ws'"
<<
endl
;
<<<<<<<
HEAD
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
<<
"--prefix-ws-max num - Максимальное количество websocket-ов"
<<
endl
;
cout
<<
"--prefix-ws-heartbeat-time msec - Период сердцебиения в соединении. По умолчанию: 3000 мсек"
<<
endl
;
cout
<<
"--prefix-ws-send-time msec - Период посылки сообщений. По умолчанию: 500 мсек"
<<
endl
;
cout
<<
"--prefix-ws-max num - Максимальное число сообщений посылаемых за один раз. По умолчанию: 200"
<<
endl
;
<<<<<<<
HEAD
cout
<<
"http: "
<<
endl
;
cout
<<
"--prefix-httpserver-host ip - IP на котором слушает http сервер. По умолчанию: localhost"
<<
endl
;
...
...
@@ -270,6 +343,16 @@ void UWebSocketGate::help_print()
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
<<
"--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
;
>>>>>>>
2.9.4
-
alt0
.1
}
// -----------------------------------------------------------------------------
void
UWebSocketGate
::
run
(
bool
async
)
...
...
@@ -426,6 +509,7 @@ void UWebSocketGate::handleRequest( Poco::Net::HTTPServerRequest& req, Poco::Net
// проверка подключения к страничке со списком websocket-ов
if
(
!
seg
.
empty
()
&&
seg
[
0
]
==
"wsgate"
)
{
<<<<<<<
HEAD
if
(
seg
.
size
()
>
2
)
{
if
(
seg
[
1
]
==
"json"
||
seg
[
1
]
==
"txt"
||
seg
[
1
]
==
"raw"
)
...
...
@@ -469,11 +553,37 @@ void UWebSocketGate::handleRequest( Poco::Net::HTTPServerRequest& req, Poco::Net
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
httpWebSocketPage
(
out
,
req
,
resp
);
<<<<<<<
HEAD
=======
>>>>>>>
2.9.4
-
alt0
.1
out
.
flush
();
}
// -----------------------------------------------------------------------------
...
...
@@ -508,7 +618,11 @@ void UWebSocketGate::onWebSocketSession(Poco::Net::HTTPServerRequest& req, Poco:
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
>>>>>>>
2.9.4
-
alt0
.1
if
(
seg
.
empty
()
||
seg
[
0
]
!=
"wsgate"
)
{
resp
.
setStatus
(
HTTPResponse
::
HTTP_BAD_REQUEST
);
...
...
@@ -516,7 +630,11 @@ void UWebSocketGate::onWebSocketSession(Poco::Net::HTTPServerRequest& req, Poco:
resp
.
setStatusAndReason
(
HTTPResponse
::
HTTP_BAD_REQUEST
);
resp
.
setContentLength
(
0
);
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"
;
>>>>>>>
2.9.4
-
alt0
.1
err
.
flush
();
return
;
}
...
...
@@ -577,22 +695,30 @@ std::shared_ptr<UWebSocketGate::UWebSocket> UWebSocketGate::newWebSocket( Poco::
std
::
shared_ptr
<
UWebSocket
>
ws
;
<<<<<<<
HEAD
RespondFormat
fmt
=
RespondFormat
::
JSON
;
=======
>>>>>>>
2.9.4
-
alt0
.1
std
::
string
slist
(
""
);
for
(
const
auto
&
p
:
qp
)
{
<<<<<<<
HEAD
// обрабатываем только первый встреченный параметр
if
(
p
.
first
==
"format"
)
fmt
=
from_string
(
p
.
second
);
else
if
(
p
.
second
.
empty
()
&&
!
p
.
first
.
empty
()
)
=======
if
(
p
.
second
.
empty
()
&&
!
p
.
first
.
empty
()
)
>>>>>>>
2.9.4
-
alt0
.1
slist
+=
(
","
+
p
.
first
);
}
if
(
qp
.
size
()
==
1
&&
qp
[
0
].
first
.
empty
()
)
slist
=
qp
[
0
].
first
;
<<<<<<<
HEAD
// auto idlist = uniset::explode(slist);
#warning DEBUG
auto
idlist
=
uniset
::
explode
(
"34,23,54"
);
...
...
@@ -611,6 +737,24 @@ std::shared_ptr<UWebSocketGate::UWebSocket> UWebSocketGate::newWebSocket( Poco::
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
);
...
...
@@ -618,6 +762,7 @@ std::shared_ptr<UWebSocketGate::UWebSocket> UWebSocketGate::newWebSocket( Poco::
ws
->
setHearbeatTime
(
wsHeartbeatTime_sec
);
ws
->
setSendPeriod
(
wsSendTime_sec
);
ws
->
setMaxSendCount
(
wsMaxSend
);
<<<<<<<
HEAD
ws
->
mylog
=
mylog
;
ws
->
setRespondFormat
(
fmt
);
...
...
@@ -629,6 +774,15 @@ std::shared_ptr<UWebSocketGate::UWebSocket> UWebSocketGate::newWebSocket( Poco::
si
.
id
=
i
;
si
.
cmd
=
"ask"
;
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
);
...
...
@@ -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
=
{
"{
\"
data
\"
: [{
\"
type
\"
:
\"
Ping
\"
}]}"
};
>>>>>>>
2.9.4
-
alt0
.1
UWebSocketGate
::
UWebSocket
::
UWebSocket
(
Poco
::
Net
::
HTTPServerRequest
*
_req
,
Poco
::
Net
::
HTTPServerResponse
*
_resp
)
:
...
...
@@ -716,10 +874,47 @@ void UWebSocketGate::UWebSocket::send( ev::timer& t, int revents )
if
(
EV_ERROR
&
revents
)
return
;
<<<<<<<
HEAD
for
(
size_t
i
=
0
;
!
wbuf
.
empty
()
&&
i
<
maxsend
&&
!
cancelled
;
i
++
)
write
();
// 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
)
...
...
@@ -810,21 +1005,38 @@ void UWebSocketGate::UWebSocket::read( ev::io& io, int revents )
}
}
// -----------------------------------------------------------------------------
<<<<<<<
HEAD
void
UWebSocketGate
::
UWebSocket
::
add
(
const
sinfo
&
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
)
{
<<<<<<<
HEAD
auto
s
=
smap
.
find
(
id
);
if
(
s
!=
smap
.
end
()
)
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
)
{
<<<<<<<
HEAD
auto
s
=
smap
.
find
(
id
);
if
(
s
!=
smap
.
end
()
)
...
...
@@ -832,6 +1044,21 @@ void UWebSocketGate::UWebSocket::set( uniset::ObjectId id, long value )
s
->
second
.
value
=
value
;
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
)
...
...
@@ -844,13 +1071,21 @@ void UWebSocketGate::UWebSocket::sensorInfo( const uniset::SensorMessage* sm )
if
(
s
==
smap
.
end
()
)
return
;
<<<<<<<
HEAD
if
(
wbuf
.
size
()
>
maxsize
)
=======
if
(
jbuf
.
size
()
>
maxsize
)
>>>>>>>
2.9.4
-
alt0
.1
{
mywarn
<<
req
->
clientAddress
().
toString
()
<<
" lost messages..."
<<
endl
;
return
;
}
<<<<<<<
HEAD
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
()
)
ioping
.
stop
();
...
...
@@ -858,21 +1093,59 @@ void UWebSocketGate::UWebSocket::sensorInfo( const uniset::SensorMessage* sm )
// -----------------------------------------------------------------------------
void
UWebSocketGate
::
UWebSocket
::
doCommand
(
const
std
::
shared_ptr
<
UInterface
>&
ui
)
{
<<<<<<<
HEAD
for
(
auto
&&
io
:
smap
)
{
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
{
if
(
s
.
cmd
==
""
)
continue
;
<<<<<<<
HEAD
if
(
s
.
cmd
==
"ask"
)
ui
->
askSensor
(
s
.
id
,
UniversalIO
::
UIONotify
);
else
if
(
s
.
cmd
==
"del"
)
ui
->
askSensor
(
s
.
id
,
UniversalIO
::
UIODontNotify
);
else
if
(
s
.
cmd
==
"set"
)
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
.
cmd
=
""
;
...
...
@@ -880,17 +1153,53 @@ void UWebSocketGate::UWebSocket::doCommand( const std::shared_ptr<UInterface>& u
catch
(
std
::
exception
&
ex
)
{
mycrit
<<
"(UWebSocket::doCommand): "
<<
ex
.
what
()
<<
endl
;
<<<<<<<
HEAD
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
)
{
uniset
::
SensorMessage
sm
(
si
.
id
,
0
);
// sm.undefined = true;
si
.
err
=
err
;
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
)
...
...
@@ -911,6 +1220,10 @@ void UWebSocketGate::UWebSocket::onCommand( const string& cmdtxt )
for
(
const
auto
&
i
:
idlist
)
set
(
i
.
si
.
id
,
i
.
val
);
<<<<<<<
HEAD
=======
// уведомление о новой команде
>>>>>>>
2.9.4
-
alt0
.1
cmdsignal
->
send
();
}
else
if
(
cmd
==
"ask"
)
...
...
@@ -921,6 +1234,7 @@ void UWebSocketGate::UWebSocket::onCommand( const string& cmdtxt )
auto
idlist
=
uniset
::
explode
(
params
);
for
(
const
auto
&
id
:
idlist
.
getList
()
)
<<<<<<<
HEAD
{
sinfo
s
;
s
.
id
=
id
;
...
...
@@ -929,6 +1243,11 @@ void UWebSocketGate::UWebSocket::onCommand( const string& cmdtxt )
}
// даём команду на перезаказ датчиков
=======
ask
(
id
);
// уведомление о новой команде
>>>>>>>
2.9.4
-
alt0
.1
cmdsignal
->
send
();
}
else
if
(
cmd
==
"del"
)
...
...
@@ -941,7 +1260,24 @@ void UWebSocketGate::UWebSocket::onCommand( const string& cmdtxt )
for
(
const
auto
&
id
:
idlist
.
getList
()
)
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
();
}
}
...
...
@@ -970,7 +1306,11 @@ void UWebSocketGate::UWebSocket::write()
int
flags
=
WebSocket
::
FRAME_TEXT
;
<<<<<<<
HEAD
if
(
msg
->
len
==
1
)
// это пинг состоящий из "."
=======
if
(
msg
->
len
==
ping_str
.
size
()
)
>>>>>>>
2.9.4
-
alt0
.1
flags
=
WebSocket
::
FRAME_FLAG_FIN
|
WebSocket
::
FRAME_OP_PING
;
try
...
...
@@ -1089,9 +1429,16 @@ void UWebSocketGate::UWebSocket::setMaxSendCount( size_t val )
maxsend
=
val
;
}
// -----------------------------------------------------------------------------
<<<<<<<
HEAD
void
UWebSocketGate
::
UWebSocket
::
setRespondFormat
(
UWebSocketGate
::
RespondFormat
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
)
...
...
@@ -1113,12 +1460,16 @@ void UWebSocketGate::httpWebSocketPage( std::ostream& ostr, Poco::Net::HTTPServe
ostr
<<
" <li><a target='_blank' href=
\"
http://"
<<
req
.
serverAddress
().
toString
()
<<<<<<<
HEAD
<<
"/wsgate/json
\"
>42,30,1042 [json]</a></li>"
<<
endl
;
ostr
<<
" <li><a target='_blank' href=
\"
http://"
<<
req
.
serverAddress
().
toString
()
<<
"/wsgate/txt
\"
>42,30,1042 [txt]</a></li>"
=======
<<
"/wsgate/?42,30,1042
\"
>42,30,1042</a></li>"
>>>>>>>
2.9.4
-
alt0
.1
<<
endl
;
ostr
<<
"</ul>"
<<
endl
;
...
...
@@ -1162,7 +1513,11 @@ void UWebSocketGate::httpWebSocketConnectPage( ostream& ostr,
ostr
<<
"{"
<<
endl
;
ostr
<<
" if (
\"
WebSocket
\"
in window)"
<<
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/?"
<<
params
<<
"
\"
);"
<<
endl
;
>>>>>>>
2.9.4
-
alt0
.1
ostr
<<
"setInterval(send_cmd, 1000);"
<<
endl
;
ostr
<<
" var l = document.getElementById('logname');"
<<
endl
;
ostr
<<
" l.innerHTML = '*'"
<<
endl
;
...
...
@@ -1189,7 +1544,11 @@ void UWebSocketGate::httpWebSocketConnectPage( ostream& ostr,
ostr
<<
" }"
<<
endl
;
ostr
<<
"function send_cmd() {"
<<
endl
;
<<<<<<<
HEAD
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
;
...
...
extensions/UWebSocketGate/UWebSocketGate.h
View file @
36839d01
...
...
@@ -55,13 +55,21 @@ namespace uniset
об изменнии датчиков, а так же изменять состояние (см. \ref sec_UWebSocketGate_Command).
Подключение к websocket-у доступно по адресу:
\code
<<<<<<< HEAD
ws://host:port/wsgate/?s1,s2,s3,s4&format=[json,txt,raw]
=======
ws://host:port/wsgate/
>>>>>>> 2.9.4-alt0.1
\endcode
Помимо этого UWebSocketGate работает в режиме мониторинга изменений датчиков.
Для этого достаточно зайти на страничку по адресу:
\code
<<<<<<< HEAD
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
\section sec_UWebSocketGate_Conf Конфигурирование UWebSocketGate
...
...
@@ -75,7 +83,93 @@ namespace uniset
\section sec_UWebSocketGate_DETAIL UWebSocketGate: Технические детали
Вся релизация построена на "однопоточном" eventloop. Если датчики долго не меняются, то периодически посылается "ping" сообщение.
<<<<<<< HEAD
\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 можно посылать команды.
На текущий момент формат команды строковый.
Т.е. для подачи команды, необходимо послать просто строку.
...
...
@@ -84,9 +178,13 @@ namespace uniset
- "set:id1=val1,id2=val2,name3=val4,..." - выставить значение датчиков
- "ask:id1,id2,name3,..." - подписаться на уведомления об изменении датчиков (sensorInfo)
- "del:id1,id2,name3,..." - отказаться от уведомления об изменении датчиков
<<<<<<< HEAD
\todo Разобраться с "ping" сообщением для формата json..
\todo Настройка check_sec из командной строки и configure.xml
=======
- "get:id1,id2,name3,..." - получить текущее значение датчиков (разовое сообщение ShortSensorInfo)
>>>>>>> 2.9.4-alt0.1
*/
class
UWebSocketGate
:
public
UniSetObject
,
...
...
@@ -149,7 +247,12 @@ namespace uniset
void
checkMessages
(
ev
::
timer
&
t
,
int
revents
);
virtual
void
sensorInfo
(
const
uniset
::
SensorMessage
*
sm
)
override
;
ev
::
timer
iocheck
;
<<<<<<<
HEAD
double
check_sec
=
{
0
.
3
};
=======
double
check_sec
=
{
0
.
05
};
int
maxMessagesProcessing
=
{
100
};
>>>>>>>
2
.
9
.
4
-
alt0
.
1
std
::
shared_ptr
<
DebugStream
>
mylog
;
...
...
@@ -162,6 +265,7 @@ namespace uniset
double
wsHeartbeatTime_sec
=
{
3
.
0
};
double
wsSendTime_sec
=
{
0
.
5
};
size_t
wsMaxSend
=
{
200
};
<<<<<<<
HEAD
enum
class
RespondFormat
{
...
...
@@ -177,6 +281,11 @@ namespace uniset
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_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
* Из-за того, что поступление логов может быть достаточно быстрым
...
...
@@ -209,11 +318,22 @@ namespace uniset
long
value
=
{
0
};
// set value
};
<<<<<<<
HEAD
void
add
(
const
sinfo
&
si
);
void
del
(
uniset
::
ObjectId
id
);
void
set
(
uniset
::
ObjectId
id
,
long
value
);
void
sensorInfo
(
const
uniset
::
SensorMessage
*
sm
);
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
();
...
...
@@ -223,19 +343,32 @@ namespace uniset
void
setHearbeatTime
(
const
double
&
sec
);
void
setSendPeriod
(
const
double
&
sec
);
void
setMaxSendCount
(
size_t
val
);
<<<<<<<
HEAD
void
setRespondFormat
(
RespondFormat
f
);
=======
void
setMaxCmdCount
(
size_t
val
);
>>>>>>>
2
.
9
.
4
-
alt0
.
1
std
::
shared_ptr
<
DebugStream
>
mylog
;
protected
:
void
write
();
<<<<<<<
HEAD
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
);
ev
::
timer
iosend
;
double
send_sec
=
{
0
.
5
};
size_t
maxsend
=
{
200
};
<<<<<<<
HEAD
=======
size_t
maxcmd
=
{
100
};
>>>>>>>
2
.
9
.
4
-
alt0
.
1
ev
::
timer
ioping
;
double
ping_sec
=
{
3
.
0
};
...
...
@@ -252,13 +385,25 @@ namespace uniset
std
::
atomic_bool
cancelled
=
{
false
};
std
::
unordered_map
<
uniset
::
ObjectId
,
sinfo
>
smap
;
<<<<<<<
HEAD
RespondFormat
fmt
=
{
RespondFormat
::
JSON
};
=======
std
::
queue
<
sinfo
>
qcmd
;
// очередь команд
>>>>>>>
2
.
9
.
4
-
alt0
.
1
Poco
::
Net
::
HTTPServerRequest
*
req
;
Poco
::
Net
::
HTTPServerResponse
*
resp
;
<<<<<<<
HEAD
// очередь данных на посылку..
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 (см. конструктор)
};
...
...
extensions/UWebSocketGate/tests/Makefile.am
0 → 100644
View file @
36839d01
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
extensions/UWebSocketGate/tests/test_uwebsocketgate.cc
0 → 100644
View file @
36839d01
#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
);
}
}
}
// -----------------------------------------------------------------------------
extensions/UWebSocketGate/tests/tests_with_sm.cc
0 → 100644
View file @
36839d01
#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
;
}
extensions/UWebSocketGate/tests/tests_with_sm.sh
0 → 100755
View file @
36839d01
#!/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
extensions/UWebSocketGate/tests/testsuite.at
0 → 100644
View file @
36839d01
m4_include(package.m4)
AT_COLOR_TESTS
AT_INIT([UWebSocketGate tests])
m4_include(uwebsocketgate-tests.at)
extensions/UWebSocketGate/tests/uniset2-functions.sh
0 → 120000
View file @
36839d01
../../../Utilities/scripts/uniset2-functions.sh
\ No newline at end of file
extensions/UWebSocketGate/tests/uniset2-start.sh
0 → 120000
View file @
36839d01
../../../Utilities/scripts/uniset2-start.sh
\ No newline at end of file
extensions/UWebSocketGate/tests/uwebsocketgate-test-configure.xml
0 → 100644
View file @
36839d01
<?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>
extensions/UWebSocketGate/tests/uwebsocketgate-tests.at
0 → 100644
View file @
36839d01
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
testsuite/testsuite.at
View file @
36839d01
...
...
@@ -14,3 +14,4 @@ m4_include(../extensions/LogicProcessor/tests/lproc-tests.at)
m4_include(../extensions/IOControl/tests/iocontrol-tests.at)
m4_include(../extensions/LogDB/tests/logdb-tests.at)
m4_include(../extensions/HttpResolver/tests/uresolver-tests.at)
m4_include(../extensions/UWebSocketGate/tests/uwebsocketgate-tests.at)
uniset2.files
View file @
36839d01
...
...
@@ -297,6 +297,17 @@
./extensions/UniNetwork/uninet.cc
./extensions/UWebSocketGate/main.cc
./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.h
./extensions/UWebSocketGate/UWebSocketGateSugar.h
...
...
@@ -390,7 +401,6 @@
./include/UTCPStream.h
./include/VMonitor.h
./include/WDTInterface.h
./lib/dummy.cc
./lib/Makefile.am
./Makefile.am
./src/Communications/ComPort485F.cc
...
...
@@ -555,6 +565,8 @@
./tests/umutex.cc
./tests/UniXmlTest/Makefile.am
./tests/UniXmlTest/XmlTest.cc
./tests/wasm-test/main.cc
./tests/wasm-test/Makefile.am
./uniset-config.h
./Utilities/Admin/admin.cc
./Utilities/Admin/c.cc
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment