[Feature-13190]How to terminate perspective session from mobile?

I’m using the ignition app on android. Even after I close the project and close the app on the phone, the gateway continues to see the session as active. How to close it properly?

It doesn’t die after a minute or three? (The session timeout.)

Nope. On the gateway, every 10 seconds I’m running system.perspective.sendMessage() to the session and the message handler in the client replies (I know it runs on the gateway too, but you know what I mean).

UPDATE: turning off the phone, it does time out on the gateway, however a number of messages are still exchanged before then (I wonder where the session values that the client sends come from…)

REPRODUCER: set a timer gateway script (run every 10 seconds) as follows:

# must be a real one, of course, yours will be different
session_id = 'd3ec351b-d8f7-4c31-895b-7eaf49c805c6'
system.perspective.sendMessage('client_handler', {}, "session", session_id)

set up a message handler msg_handler on the gateway as follows:

session_id = payload['session_id']
logger = system.util.getLogger('mylogger')
logger.info('received message from session %s' % session_id)

On the main perspective view, set up this message handler client_handler on the root container:

logger = system.util.getLogger('mylogger')
logger.info("Received message from gateway")
payload = {'val': self.session.custom.myvalue, 'session_id': self.session.props.id}
system.util.sendMessage(project = 'myproject', messageHandler = 'msg_handler', payload = payload)

Run the project in the app, note the session id and use it for the gateway timer script. Watch the message exchange happen for some time if you want, then close the project in the app, close the app, and see how the exchange happily continues.

Are you sure you’ve closed/killed the app and not just backgrounded it? That would explain why shutting the phone off behaves differently…

My bad: while I did do “force stop” for the app to terminate it, I had en extremely high timeout in the perspective project properties, which I have now lowered.
However, when shutting off the phone, the exchange goes on for some time before the “end session” event, that is definitely weird. I’d expect it to terminate immediately.

The bulk of what makes of a Perspective Session is actually running in the gateway. All the scripts, expressions, bindings, and anything else important live here and are evaluated here.

The session your browser has is mostly just a view into what’s happening on the gateway. The gateway session doesn’t know the browser disappeared until some keep alive mechanism fails and it decides it’s really time to end.

Until that keep alive mechanism fails the session in the gateway is live.

Well ok, but if the gateway detects that the websocket gets closed (which it does, since the message appears in the logs), perhaps it should stop pretending that the client is alive…

I think the intention here is that the session can be resumed, but I’m not involved enough in Perspective to say for sure. Maybe someone else can clarify.

Makes sense, but at the risk of accessing stale session data in the meanwhile…

To my recollection this is indeed the case; you don’t want a momentary hiccup in wifi connectivity to cause loss of your session. Same thing in case you accidentally close your browser tab. We could conceivably provide some sort of system.perspective.retireSession() function which would result in the Gateway terminating the session from which the script was called, but I’m not sure how we would handle that in the browser. Would all open tabs swap to a terminal page? How do we force that terminal state and what does it look like?

Not easy questions, and definitely not something we have time for in the coming weeks, but I’ll open a feature ticket for it.

1 Like

My use case is simple: I don’t want to be reading stale GPS data (which is stored in the session), so at the very least I’d like to have a way to tell whether a session is disconnected or not; otherwise I’d see runs of unchanged coordinates coming from the session and I wouldn’t be able to tell whether it’s because the device is really not moving or because the session is disconnected (ie, websocket closed, which I guess prevents GPS coordinates from updating).
Otherwise, you could make GPS coordinates collection work like barcode scanning, ie collected on the client (perhaps with user-configurable frequency) then sent to the gateway in batches when connectivity allows. This would also solve the issue I’m describing.

I opened an internal feature request, but in the meantime (and assuming our implementation requires a user to manually trigger a session termination) you can rig something similar up:

  1. Create a new Session custom property with a key of “retired” and set the value to false.
  2. Place a Button which will be used to Terminate Session somewhere (most likely a Header/Footer which is always displayed).
  3. When the Button is clicked, set self.session.custom.retired to have a value of true.
  4. Now when your Session receives calls to update the GPS coordinates (from Tracking perspective app coordinates), check against the retired session property, and if it is false, don’t send the response.

Sorry for being slow to understand, but is clicking the button while the session is disconnected going to produce a property change visible from the gateway? Or, when is that button supposed to be clicked?

No, this is only changing a property for the individual session to (until we can implement the requested feature) stop sending out GPS data. It is meant to be clicked when a user is done and intends to no longer use their session. It would have absolutely NO EFFECT on the session other than to set that property. This will prevent your stale data from being sent to the Gateway, but if a user chooses to click this button and then continue using the session, well… we can only help you so far before the feature is in place.

That’s not the problem at hand; users are roaming with their devices, and will most likely end up in zones with poor connectivity and gateway connection will be lost for some time (I see “websocket closed” in the gateway log when this happens). During this time, the gateway keeps sending GPS coordinate requests to the session, and the session happily replies with stale data (the last known GPS values), which is what I want to avoid, because that would be indistinguishable from the user device being still. However, I cannot ask users to click a button to block GPS sending when they foresee they are entering an area with poor connectivity. It should be detected at the gateway end, imho.
For the time being, I’m going to set the perspective session timeout as low as possible in the project properties, so at least the session is terminated as soon as possible when disconnected.

How would the Gateway determine a Session is no longer active, or has become disconnected?

If you’re on the phone with someone and they stop participating in a conversation, how do you determine they are still on the line? You ask if they’re still present. Maybe you ask once a second for n seconds. Eventually, you decide they are no longer on the line, and you hang up. This is what the Session timeout settings are for.

There is no way for the Gateway to know that a user’s Session needs to be terminated right this very second due to the user leaving an area which had connectivity.

Just because the websocket connection has closed does not mean the Session should be ended/terminated; suppose I went from one warehouse to another, and lost wifi connectivity for five seconds… should my session be lost? What if I accidentally close my browser tab - do I lose changes I’ve made?

Having the gateway terminate sessions automatically is overkill and unfeasible, I agree. However providing some means to detect that the connection is closed (a session variable; some kind of catchable failure in system.perspective.sendMessage(); or whatever else you think could be adequate) could help user code running on the gateway make better/more informed choices (in my case, I would just avoid requesting GPS data).

We can add a session property for whether or not the websocket connection is live.

1 Like

That would be very helpful. By the way, is there a way to access the properties of a given session from a gateway script (ie, without having to use message passing)? Otherwise one additional message exchange would be necessary only to test for websocket status, before the real message exchange could take place.

Thank you very much!

I would prefer to see an ever-changing timestamp tracking the last websocket packet arrival…

That allows variable levels of timeout precision for different purposes.