Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
erp5
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Levin Zimmermann
erp5
Commits
acb150c7
Commit
acb150c7
authored
Mar 07, 2023
by
Levin Zimmermann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add basic opcua server
this is a very dirty adhoc approach: we basically build our own asyncua.Server.
parent
d630a237
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
78 additions
and
0 deletions
+78
-0
product/ERP5/bin/zopewsgitw.py
product/ERP5/bin/zopewsgitw.py
+78
-0
No files found.
product/ERP5/bin/zopewsgitw.py
View file @
acb150c7
...
...
@@ -250,11 +250,23 @@ def runwsgi():
#
################################################################
import
math
# We need asyncio support in twisted because our opcua lib is written with
# asyncio syntax. See https://meejah.ca/blog/python3-twisted-and-asyncio
import
asyncio
from
twisted.internet
import
asyncioreactor
asyncioreactor
.
install
(
asyncio
.
get_event_loop
())
from
twisted.internet.task
import
react
from
twisted.internet.defer
import
ensureDeferred
from
twisted.web.wsgi
import
WSGIResource
from
twisted.internet
import
protocol
,
reactor
,
endpoints
from
twisted.web
import
server
as
twisted_server
import
urllib
import
asyncua
from
Products.ERP5Type.Log
import
log
# I modified runwsgi() without thinking carefully.
...
...
@@ -394,6 +406,37 @@ def runwsgitw():
def
buildProtocol
(
self
,
addr
):
return
Echo
()
class
OPCUA
(
protocol
.
Protocol
,
asyncua
.
server
.
binary_server_asyncio
.
OPCUAProtocol
):
def
__init__
(
self
,
*
args
,
**
kwargs
):
asyncua
.
server
.
binary_server_asyncio
.
OPCUAProtocol
.
__init__
(
self
,
*
args
,
**
kwargs
)
protocol
.
Protocol
.
__init__
(
self
)
def
dataReceived
(
self
,
data
):
log
(
"data received"
)
log
(
data
)
self
.
data_received
(
data
)
log
(
"PASSED data received"
)
def
connectionMade
(
self
):
log
(
"connection made"
)
# opcua transport has 'get_extra_info':
# https://github.com/FreeOpcUa/opcua-asyncio/blob/ff6969d/asyncua/server/uaprocessor.py#LL32-L32C61
self
.
transport
.
get_extra_info
=
lambda
*
args
,
**
kwags
:
"test"
# this also has 'close'
# https://github.com/FreeOpcUa/opcua-asyncio/blob/master/asyncua/server/binary_server_asyncio.py#L108
self
.
transport
.
close
=
lambda
*
args
,
**
kwags
:
None
self
.
connection_made
(
self
.
transport
)
log
(
"PASSED conn made"
)
def
connectionLost
(
self
,
ex
):
log
(
"connection lost"
)
self
.
connection_lost
(
ex
)
log
(
"PASSED conn lost"
)
class
OPCUAFactory
(
protocol
.
Factory
):
def
buildProtocol
(
self
,
addr
):
return
OPCUA
(
self
.
iserver
,
[],
[],
[],
self
.
limits
)
# Add a wsgi server, this is normal.
endpoints
.
serverFromString
(
reactor
,
"tcp:%s:interface=%s"
%
(
port
,
ip
)).
listen
(
twisted_server
.
Site
(
resource
))
...
...
@@ -402,5 +445,40 @@ def runwsgitw():
# to a different port.
endpoints
.
serverFromString
(
reactor
,
"tcp:2261:interface=%s"
%
ip
).
listen
(
EchoFactory
())
# Add OPCUA server
opcua_ip
,
opcua_port
=
ip
,
'2262'
opcua_factory
=
OPCUAFactory
()
add_iserver
(
opcua_factory
)
add_limits
(
opcua_factory
)
endpoints
.
serverFromString
(
reactor
,
f"tcp:
{
opcua_port
}
:interface=
{
opcua_ip
}
"
).
listen
(
opcua_factory
)
# Start main loop.
reactor
.
run
()
def
add_iserver
(
opcua_factory
,
opcua_ip
,
opcua_port
):
opcua_factory
.
iserver
=
asyncua
.
server
.
internal_server
.
InternalServer
()
# see https://github.com/FreeOpcUa/opcua-asyncio/blob/ff6969d2/asyncua/server/server.py#LL411C13-L411C70
opcua_factory
.
iserver
.
supported_tokens
=
(
asyncua
.
ua
.
AnonymousIdentityToken
,)
# adhoc creation of endpoint, only most essential parts
# https://github.com/FreeOpcUa/opcua-asyncio/blob/ff6969d2b7d93cc22c517cbb2f43ef98dc643a8c/asyncua/server/server.py#L434
edp
=
asyncua
.
ua
.
EndpointDescription
()
edp
.
EndpointUrl
=
urllib
.
parse
.
urlparse
(
f"opc.tcp://
{
opcua_ip
}
:
{
opcua_port
}
/freeopcua/server/"
).
geturl
()
edp
.
SecurityMode
=
asyncua
.
ua
.
MessageSecurityMode
.
None_
edp
.
SecurityPolicyUri
=
asyncua
.
ua
.
SecurityPolicy
.
URI
opcua_factory
.
iserver
.
add_endpoint
(
edp
)
def
add_limits
(
opcua_factory
):
# Use acceptable limits
buffer_sz
=
65535
max_msg_sz
=
100
*
1024
*
1024
# 100mb
opcua_factory
.
limits
=
asyncua
.
common
.
connection
.
TransportLimits
(
max_recv_buffer
=
buffer_sz
,
max_send_buffer
=
buffer_sz
,
max_chunk_count
=
math
.
ceil
(
max_msg_sz
/
buffer_sz
),
# Round up to allow max msg size
max_message_size
=
max_msg_sz
)
\ No newline at end of file
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