I've upgraded an application from Ignition 8.1.16 to Ignition 8.1.17
I have a module that send message to perspective pages.
All works fine in 8.1.16, but after upgrading in 8.1.17, the message are not sent or received in the event bus.
Does anything change in the way to send page's message ?
The code used by the module to send message:
public void sendCallbackMessage(String strSessionId,String pageId,String sessionName,Dataset data) {
try {
UUID sessionId = UUID.fromString(strSessionId);
perspectiveContext.getSessionMonitor().findSession(sessionId).ifPresent(session -> {
Optional<PageModel> pageModel = session.findPage(pageId);
if (pageModel.isPresent()){
PyDictionary payloadMap = new PyDictionary();
QualifiedValue value = new BasicQualifiedValue(data);
payloadMap.put("data", value);
UserScopeMessageEvent message = new UserScopeMessageEvent(sessionName, payloadMap);
logger.debug("sendCallbackMessage() send to sessionName={} - sessionId={} - pageId={} - data={}",
sessionName,
sessionId.toString(),
pageId,
value);
session.queue().submit(() -> pageModel.get().getPageEventBus().post(message));
} else {
logger.error("sendCallbackMessage() - sessionId={} - pageId={} not found !",
sessionId.toString(),
pageId);
}
});
} catch (Exception e) {
logger.error("sendCallbackMessage() - Exception : {}",e);
}
}
According to gateway and browser logs, session id and page id are OK,
nevertheless the message handler that is no more triggered since upgrading in 8.1.17:
Instead of subscribing to the page eventbus, subscribe to the page’s event manager (you’ll have to bump your SDK version). There was a catastrophic performance cliff in Guava’s eventbus, so we had to migrate away. The API is roughly the same, but the internals are different.
Yeah, pretty much everything in Perspective was refactored to have the two side by side. I think we’re planning to remove the eventbus stuff in Perspective in 8.2.X, but I’m not positive on that.
If you plan to use Perspective APIs in your code, you must do two things:
At compile time of your module, provide the appropriate Perspective SDK dependencies via your build system of choice.
Declare a dependency on the Perspective module in your module.xml, so that Ignition knows to load your code (on the Gateway, at least) within an appropriate classloader.
If you want to handle Perspective being optional, things get somewhat more complicated and can require reflection to handle cleanly.
No, there are no Maven archetypes for a Perspective component. We use Gradle internally, and no one (to my knowledge) has yet figured out how to build a Perspective component with Maven.
There are two public examples of a Perspective component built using Gradle:
In relation to the above, I have got this mechanism working with Message Handlers on views (root). But I can't seem to get this to work with the Perspective Session Events mechanism. Am I supposed to be doing something different?
It's not clear at all to me what issue you're having or how it relates to the above. Are you also developing a module? What have you done/what are you currently doing/what's going wrong?
I can only register that message on the client, if I put my message handler on one of the pages in my project (I used the root for this test).
What I actually want to do, is have the message handler in the Perspective Session Events. I tested it with the Session Events and it seems that I cannot handle the message being sent from my module.
Ah, yeah. The former are messages sent via (typically) system.util.sendMessage, on an overall platform-level bus. The latter are messages sent via system.perspective.sendMessage, on a Perspective-specific bus. To use the overall system bus, you want the MessageDispatchManager you get from GatewayContext. You build up a Properties instance with the static string constant keys in MessageDispatchManager.
Yes, the ProjectName will come from the configuration eventually. It is easier to ignore that for now.
One last question, is there a way that I can display a Popup from the Perspective Session Events handler.
com.inductiveautomation.ignition.common.script.JythonExecException: Traceback (most recent call last): File "", line 2, in handleMessage at com.inductiveautomation.perspective.gateway.script.AbstractScriptingFunctions.lambda$operateOnPage$0(AbstractScriptingFunctions.java:64) at com.inductiveautomation.perspective.gateway.script.AbstractScriptingFunctions.operateOnSession(AbstractScriptingFunctions.java:120) at com.inductiveautomation.perspective.gateway.script.AbstractScriptingFunctions.operateOnPage(AbstractScriptingFunctions.java:47) at com.inductiveautomation.perspective.gateway.script.PerspectiveScriptingFunctions.popupAction(PerspectiveScriptingFunctions.java:758) at com.inductiveautomation.perspective.gateway.script.PerspectiveScriptingFunctions.openPopup(PerspectiveScriptingFunctions.java:240) 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) java.lang.IllegalArgumentException: java.lang.IllegalArgumentException: No perspective page attached to this thread.
at org.python.core.Py.JavaError(Py.java:547)
at org.python.core.Py.JavaError(Py.java:538)
at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java:192)
at com.inductiveautomation.ignition.common.script.ScriptManager$ReflectedInstanceFunction.__call__(ScriptManager.java:552)
at org.python.core.PyObject.__call__(PyObject.java:477)
at org.python.core.PyObject.__call__(PyObject.java:481)
at org.python.pycode._pyx351.handleMessage$1(:2)
at org.python.pycode._pyx351.call_function()
at org.python.core.PyTableCode.call(PyTableCode.java:173)
at org.python.core.PyBaseCode.call(PyBaseCode.java:306)
at org.python.core.PyFunction.function___call__(PyFunction.java:474)
at org.python.core.PyFunction.__call__(PyFunction.java:469)
at org.python.core.PyFunction.__call__(PyFunction.java:464)
at com.inductiveautomation.ignition.common.script.ScriptManager.runFunction(ScriptManager.java:846)
at com.inductiveautomation.ignition.common.script.ScriptManager.runFunction(ScriptManager.java:828)
at com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle$TrackingProjectScriptManager.runFunction(ProjectScriptLifecycle.java:832)
at com.inductiveautomation.ignition.common.script.ScriptManager$ScriptFunctionImpl.invoke(ScriptManager.java:1009)
at com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle$AutoRecompilingScriptFunction.invoke(ProjectScriptLifecycle.java:897)
at com.inductiveautomation.perspective.gateway.script.ScriptFunctionHelper.invoke(ScriptFunctionHelper.java:147)
at com.inductiveautomation.perspective.gateway.script.ScriptRunner.run(ScriptRunner.java:23)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at com.inductiveautomation.perspective.gateway.threading.BlockingWork$BlockingWorkRunnable.run(BlockingWork.java:58)
at java.base/java.lang.Thread.run(Unknown Source)
Caused by: org.python.core.PyException: java.lang.IllegalArgumentException: java.lang.IllegalArgumentException: No perspective page attached to this thread.
... 26 common frames omitted
Caused by: java.lang.IllegalArgumentException: No perspective page attached to this thread.
at com.inductiveautomation.perspective.gateway.script.AbstractScriptingFunctions.lambda$operateOnPage$0(AbstractScriptingFunctions.java:64)
at com.inductiveautomation.perspective.gateway.script.AbstractScriptingFunctions.operateOnSession(AbstractScriptingFunctions.java:120)
at com.inductiveautomation.perspective.gateway.script.AbstractScriptingFunctions.operateOnPage(AbstractScriptingFunctions.java:47)
at com.inductiveautomation.perspective.gateway.script.PerspectiveScriptingFunctions.popupAction(PerspectiveScriptingFunctions.java:758)
at com.inductiveautomation.perspective.gateway.script.PerspectiveScriptingFunctions.openPopup(PerspectiveScriptingFunctions.java:240)
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)
at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java:190)
Because I get this error, so I am assuming I can't use system.perspective.openPopup without calling from within a Perspective View?