[IGN-6563]Retrieve Session custom props remotely

I know that with system.perspective.getSessionInfo() you can get some generic session information. However is it possible to get perspective session custom props remotely?

I have synced them to the database in the past, but I am looking for a solution that is a bit more elegant.

I appreciate any info!

Perhaps using system.util.sendRequest() to return them from the project?

I thought about that, but I wasn’t sure how I would get the session props out of the project scope either.

Session custom props are unique to a particular running session, so you would need to pass a particular session ID.

If you have something truly ‘global’, then it would probably be better off living in system.util.getGlobals() than a session custom property?

I am actually open to this, but I can't figure out where to send a sessionId to get its props.

Maybe some clarification on what I am trying to do would help. I am trying to get the session props for remote monitoring of a specific session. That way I can see debug details about a users session remotely, without needing to sync them all into a database. Ideally a system.perspective.getSessionInfo(id=sessionId) would be great but it doesn't provide the custom props. Or even a system.util.sendRequest(projectName, "getSessionProps", sessionId=sessionId) would be fine, maybe easier to provide them to the gateway scope. However I can't find any way to send a request directly to a session, or just do a lookup on those props by their ID from the gateway scope.

EDIT: One way to do this would be by putting them in the globals with a WeakRef key that is a reference to the session, but you can't grab the true session reference because of the safety wrappers :slightly_frowning_face:, so you risk memory leaks if things aren't cleaned up correctly.

How about a really hacky way to do it?

system.util.sendMessage(projectName, "requestSessionProps", {callBackServer=remoteServerAddress, sessionId=sessionId})

Then in the requestSessionProps handler call system.perspective.sendMessage('getSessionProps',{server=remoteServerAddress}, 'S',sessionId) to a handler in the session, which packages the custom props and uses system.util.sendMessage() to return the props?

Not sure I would call that elegant, but it might work.

Okay, so this does work, it's dirty, but it technically works.

Digging around in this I found that the documentation says that the documentation says system.util.sendRequest is a valid caller for Session Message Handlers:

The Message Handler scripts will run whenever the Session receives a message from system.util.sendMessage or system.util.sendRequest.

However the clientSessionId and scope params don't seem to be valid kwargs for system.util.sendRequest. Is this a documentation error or potentially a bug? (I really hope the answer is fixable bug, because that solves my problem the best lol)

The intention in the code appears to be that a sessionId or clientSessionId kwarg will both be accepted by both functions and do the ‘right’ thing in Perspective.

Looks like there may be a bug unless I have something wrong here

My Caller (On a perspective button for testing):

sessionId = self.session.props.id
response = system.util.sendRequest(project="MES", messageHandler="getSessionProps", payload={}, scope="S", clientSessionId=sessionId)

The Message Handler (getSessionProps)

system.util.getLogger("SessionProps").info("Request Received: %s" % (session.custom))
return session.custom

The Exception:

Error running action 'component.onActionPerformed' on Test@D/root/Button: Traceback (most recent call last): File "<function:runAction>", line 3, in runAction at com.inductiveautomation.ignition.common.script.message.MessageHandlerManager.processRequest(MessageHandlerManager.java:195) at com.inductiveautomation.ignition.common.script.ScriptConfig.invokeGWRequestHandler(ScriptConfig.java:242) at com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle.dispatchScriptMessage(ProjectScriptLifecycle.java:552) at com.inductiveautomation.ignition.gateway.project.IgnitionProjectManager.invokeGWMessageHandler(IgnitionProjectManager.java:189) at com.inductiveautomation.ignition.gateway.clientcomm.scriptmsg.MessageDispatchManagerImpl.doGatewayNotification(MessageDispatchManagerImpl.java:538) at com.inductiveautomation.ignition.gateway.clientcomm.scriptmsg.MessageDispatchManagerImpl.dispatchLocal(MessageDispatchManagerImpl.java:338) at com.inductiveautomation.ignition.gateway.clientcomm.scriptmsg.MessageDispatchManagerImpl.dispatchRequest(MessageDispatchManagerImpl.java:204) at com.inductiveautomation.ignition.gateway.script.GatewaySystemUtilities.sendRequestInternal(GatewaySystemUtilities.java:288) at com.inductiveautomation.ignition.common.script.builtin.SystemUtilities.sendRequestInternal(SystemUtilities.java:907) at com.inductiveautomation.ignition.common.script.builtin.SystemUtilities.sendRequest(SystemUtilities.java:828) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.base/java.lang.reflect.Method.invoke(Unknown Source) com.inductiveautomation.ignition.common.script.message.MessageHandlerException: com.inductiveautomation.ignition.common.script.message.MessageHandlerException: The message handler "getSessionProps" could not be found! Check your event script message handlers.

Here is the project export:
SendRequestProject.zip (6.1 KB)

it looks like you might have tried something similar to this before, but it’s not clear why it didn’t work for you.

From a Button in the session requesting props:

system.util.sendMessage("<ThisProjectName>", "REQUEST_PROPS", payload={"requestSessionId": self.session.props.id}, clientSessionId="<someTargetSessionid>", scope="S")

Message Handler (REQUEST_PROPS)

props_object = {}. # build out what you want to send back here.
system.util.sendMessage("<ThisProjectName>", "RECEIVE_PROPS", payload=props_object, clientSessionId=payload["requestSessionId"], scope="S")

Then you just need a second handler (RECEIVE_PROPS) for processing the props returned from REQUEST_PROPS.

1 Like

A back and forth sendMessage did work it was just a bit dirtier, and lacked some of the determinism of a sendRequest. The issue was primarily that sendRequest was documented to work as well, and it seems it doesn't work as expected. Being able to put a sendRequest on a custom prop would make it much easier to put together a screen that does what I want in retrieving client session details.

Oh. You’ve set up getSessionProps as a SESSION Event message Handler, but it needs to be a GATEWAY Event message handler.

This is going to render sendRequest useless because you’re now out of the Session scope.

Update: I see you’ve referenced a part of the Docs which claims that sendRequest should trigger Session Events as well, but… this is news to me. I’ve never tried that and to my knowledge we have no testing to confirm this. I’m looking into it.

2 Likes

I also have a use-case for bidirectional/inter-session communication and I'm assuming (perhaps incorrectly) from [IGN-6563] in the subject that this became a bug/support ticket - any chance there's been a resolution?

6563 is an internal feature ticket that hasn't yet been picked up.
The gist of the ticket is "make it possible to do more dynamic/meta stuff in Perspective, via scripts and expressions". Stuff like returning the view's own ID via {view.id}, or get a 'live' session object given the ID via some system.perspective.getSession() function. Stuff like that should act as 'building blocks' to allow functionality more like what you're looking for on top.

4 Likes