Closed jmarshall9120 closed 1 year ago
Automatic reconnecting is on my list for upcoming features.
client = Client(...)
while 1:
connected = False
try:
async with client:
print('Connected')
...
await client.create_subscription(...)
await subscription.subscribe_data_change(...)
while 1:
await asyncio.sleep(1)
await client.check_connection() # Throws a exception if connection is lost
except (ConnectionError, ua.UaError):
if connected:
print('Connection failed')
else:
print('Connection Lost')
print('Retry in 5 seconds')
await asyncio.sleep(5)
Maybe adding an example is a good idea, because this questions are popping up from time to time.
in case of "long" running subscriptions be aware that you might need to create a new subscription if the lifetime of the subscription is reached and gets closed by the server. that can happen if you subscribe relatively static data while having a too short publishinginterval.
one quick fix to check if that is the reason would be to subscribe the servertime "i=2258" [Server_ServerStatus_CurrentTime] with queuesize 1 so you will never ever have a keep alive
Reference: https://reference.opcfoundation.org/Core/Part4/v104/5.13.1/
Subscriptions have a lifetime counter that counts the number of consecutive publishing cycles in which there have been no Publish requests available to send a Publish response for the Subscription. Any Service call that uses the SubscriptionId or the processing of a Publish response resets the lifetime counter of this Subscription. When this counter reaches the value calculated for the lifetime of a Subscription based on the MaxKeepAliveCount parameter in the CreateSubscription Service (5.13.2), the Subscription is closed. Closing the Subscription causes its MonitoredItems to be deleted. In addition the Server shall issue a StatusChangeNotification notificationMessage with the status code Bad_Timeout. The StatusChangeNotification notificationMessage type is defined in 7.20.4.
I am experiencing the same problem with relatively static data. After a while the subscription is suddenly dropped. I believe this should not happen because, according to the OPC UA documentation, the lifetime should be reset by continuously making publish requests. I think this is also more logical than subscribing to a node that is not relevant. Should _publish_loop in ua_client.py not solve this problem? Perhaps there is a bug related to the publish request?
Looking at the code it seem that the problem I am experiencing is because only one publish task, thus only one publish loop, can be created per client.
relatively static data. After a while the subscription is suddenly dropped. I believe this should not happen because, according to the OPC UA documentation, the lifetime should be reset by continuously making publish requests. I think this is also more logica
Hi @schroeder- i tested your code snippets but i found that it throw an error, seems like the client object does not have a function of check connection, could you help me with this? thanks a lot! await client.check_connection() # Throws a exception if connection is lost AttributeError: 'Client' object has no attribute 'check_connection'
That error means you are using an old version. Upgrade
Also yes. Do as @schroeder- does. That is the correct way to do that kind of things. Maybe recreate the client object too. Many users are using that client for weeks so it works. If you have an issue you are doing something special somewhere
That error means you are using an old version. Upgrade
Thank you very much! Oroulet.
Also yes. Do as @schroeder- does. That is the correct way to do that kind of things. Maybe recreate the client object too. Many users are using that client for weeks so it works. If you have an issue you are doing something special somewhere
Yes i strongly recommended adding this codesnippet as an example in the master so other people didnt need to search the issues to find some possible solutions. :)
Yes that example was nice. Will do
@schroeder- Got back to playing with this today. I added your code snippet to my example. After about 1.5hours I get this as an error:
Begin update : 154 - d: 1:32:49.773865 - s:2022-11-06 16:57:10.751636
Error while renewing session
Traceback (most recent call last):
File "m:\source\bandz-padline-webserver\venv\lib\site-packages\asyncua\client\client.py", line 474, in _renew_channel_loop
await self.open_secure_channel(renew=True)
File "m:\source\bandz-padline-webserver\venv\lib\site-packages\asyncua\client\client.py", line 339, in open_secure_channel
result = await self.uaclient.open_secure_channel(params)
File "m:\source\bandz-padline-webserver\venv\lib\site-packages\asyncua\client\ua_client.py", line 307, in open_secure_channel
return await self.protocol.open_secure_channel(params)
File "m:\source\bandz-padline-webserver\venv\lib\site-packages\asyncua\client\ua_client.py", line 222, in open_secure_channel
raise RuntimeError('Two Open Secure Channel requests can not happen too close to each other. ' 'The response must be processed and returned before the next request can be sent.')
RuntimeError: Two Open Secure Channel requests can not happen too close to each other. The response must be processed and returned before the next request can be sent.
I'm digging in now. Any ideas are appreciated.
I made a PR for example. and tested it by killing the server a few times. it workes. I suppose someone with more time can try to play with the different timeouts to see if that works in all cases
I've been testing for a couple days and upgrading my version of the 'asyncua' library. A lot seems to have changed and it's still very unclear from documentation and examples how a practical subscription use, in an app will work. I would suggest any practical use case would require very robust connectivity:
Below is an example of me testing against a live server. I'm happy to work on this and submit a PR. There are so many use case questions that come up:
I ran into all kinds of bugs yesterday from, exceeding max sessions to uncaught errors in other concurrent code blocks that threw errors when I tried to asycnio.sleep. I've updated to the latest version: 0.9.98 and am testing again today to see what pops.