Reconnect Milo Client - opc-ua

I want the Client to reconnect to the Server if the server went down and up again. I can add an SessionActivityListener to the Client which gets notified on SessionInactive and the SessionActive if the Server is back online. However, when i get the SessionActive and try to resubscribe i get an "secure channel invalid" error message.
14:32:28.209 [ua-netty-event-loop-11] ERROR o.e.m.o.s.c.h.UaTcpClientAcknowledgeHandler - [remote=/127.0.0.1:53530] Received error message: ErrorMessage{error=StatusCode{name=Bad_SecureChannelIdInvalid, value=0x80220000, quality=bad}, reason=Bad_SecureChannelIdInvalid (code=0x80220000, description="The specified secure channel is no longer valid.")}
so what i'm currently doing is, disconnect the client and create a completely new client with the same subscriptions as the old client. but i guess thats pretty hacky. so the question is, is there a way to just update the "old" clients connection and subscriptions?
i'm currently testing with the prosys simulation server
greetings,
Lukas

Once the client has successfully connected it will automatically reconnect any time the connection is broken. It will attempt to resume the old session or create a new session automatically if necessary, and try to transfer subscriptions if a new session was created. This is all handled for you.
Subscription transfer may fail or not be supported by the server, in which case you need to re-create the subscriptions yourself. You should add a SubscriptionListener to the OpcUaSubscriptionManager and implement the onSubscriptionTransferFailed callback, which notifies you that transfer failed and you need to re-create this subscription yourself.

Related

Postgres - Locking insertion of non-existing row until transaction is committed

I have an application in which there are users, issuers, certificates and issues. users are the basic account, and issuers are the upgraded accounts who are able to distribute certificates to users. And distributing of certificates are called issues. The app uses postgres 14.4.
There is something called 'passive issue' in the application, which refers to issue of a certificate to a user that is not yet registered. Passive issue executes a transaction as follows:
check if user exists, if it does ignore it, if it does not, continue
create a passive issue which has awaiting register status
and then when that user actually registers, a trigger fires and updates the issue status.
The problem is that, after checking if user exists, and it does not, but right at that moment the user creates the account, and we try to passive issue, it will throw an error saying user already exists.
There are 2 possible approaches to solve this you might have thought so far:
just catch and check the error and redirect it to normal issuing path rather than passive issue within the api itself
return the error and let client retry the request by sending a request to normal issue path
The problem with above solutions:
It can not be done. Simply because this application uses blockchain, and normal issue endpoint requires the signature of the issuer. Passive issue is specifically implemented to be sent without a signature, and signature is generated on the client-side. And sending the private key to api is NOT even a possibility due to security concerns.
This is possible. This way the client will be noticed that this account registered, and it can prepare the signature and directly send a request to normal issue api. But it requires a longer and more complex implementation with retry logic etc.
And what I think would be the most neat solution in my case is such a scenario of passive issue:
check if user exists, and if it doesn't, lock the insert into the user table for that specific email ONLY
create passive issues for those accounts with await registration status (tx committed at this point and lock is released)
now even if the user tried to register in the middle, it will wait until issues are created and then user will be registered, and then trigger will fire, and since there are passive issues on this user now, it will update them.
So... Long story short: is there a way to put a lock on insertion of non-existing rows? And if there is, is it more feasible than the 2nd or any other possible solution?

Why won't my service connection stay verified?

I am working on this problem and want to ensure my service connection is verified.
When I click Verify Connection I do get a green connection verified tick.
Then I close the dialog
When I open the dialog again it says the connection is not verified.
Since I am actually able to build a release i guess that this is just a strange behaviour in the UI

REST APIs: How to ensure atomicity?

I am developing a small REST API. As I got into analyzing all the possible failure scenarios, which I have to handle to create a reliable and stable system, I went into thinking about how to make my APIs atomic.
If we take a simple case of creating a contact through the POST API.
The server gets the POST request for the new contact.
Creates the contact in the DB.
Creates a response to send back to the client.
The server crashes before sending the response.
The client gets a timeout error (or connection refused?)
The client is bound to think that the contact creation has failed, though, in fact, the contact was in the DB.
Is this a rare case we can ignore? How do big companies deal with such an issue?
To handle this, you should make your write APIs idempotent i.e. If the same operation is executed multiple times, the result should be same as the operation was done only once.
To achieve this in your current example, you need to be able to identify a contact uniquely based on some parameter, say emailAddress. So, if the createContact is called again with the same emailAddress, check in the DB if a contact already exists with the emailAddress. If so, return the existing contact. Else, create a new contact with the emailAddress and return it.
Hope this helps.
If the request times out, the client should not make any assumption about whether it failed or succeeded.
If it is just a user making a request from a web form, then the timeout should just be exposed to the user, and they can hit the back button and check whether the operation succeeded or not, and if not they submit the request again. (This is fine as long as you always keep a consistent state. If your operation has multiple steps and fails mid way, you need to roll back.)
However if reliable messaging is important to your application you will have to use a library or build your own reliable messaging layer. This could work by having the client assign a unique ID to every request, and having another request that lets you check the result of that request ID later. Then you can do automated retries but only where necessary.

Checking for other UIRemoteNotifications waiting, inside didReceiveRemoteNotifications

In didReceiveRemoteNotification, is it possible to see if there are other/older push notifications that haven't been responded to?
I have a scenario where each notification contains different data, and unless you exit app and select every single notification for your app. You app wont be able to get to that data.
I'm thinking that iOS must be storing that information in an array somewhere, but haven't been able to find anything through Google.
Advice please? Last chance saloon would be re-writing it to poll a server for notifications.
You cannot guarantee that your app will ever receive any push notification sent to it. The only way it does is if it is running when it receives the message or if the notification is used to launch your app.
I would recommend implementing a web service on your server that allows your app to pull down the data it needs from these notifications when it is running.

Push Notification to my app not the user

I want to notify my app that there is new data available but I do not want my app to constantly polling my server = checking for it new user data wasting user data and killing the users battery.
Instead it would be nice to send a message to my app letting it know there is new data ready to consume.
Just don't register for alerts then the user won't get the alerts when the app isn't open but if the app is open you can still respond to notifications silently or how you choose.
Or: (this will save yours and users bandwidth)
When the app closes send a message to your server telling it that the app is closed and not to send new notifications. Then when the app starts send a message to the server telling it to send notifications.
EDIT: unless you want to have the app open automatically or download the new content in the background, in which case that isn't possible.
Isn't this the default behavior?, your application will be notified with a callback by the Push Notification server whenever there is new data.
You can open socket to your server an d make it listen for data - this option will drain user battery, maybe not so fast as frequent HTTP requests.
Also you can try do those HTTP request, but make them as long-poll. For example application will request some URL and server will hold that connection for specific amount of time or response something is there is data available for the user. When connection closed, your application should reopen it.