The Name Of My Page"
m |
|||
Line 26: | Line 26: | ||
<b>AlarmsReceive.java is Servlet 3.0.</b> | <b>AlarmsReceive.java is Servlet 3.0.</b> | ||
− | <br>[[File: | + | <br>[[File:Import.png]] |
<br><br>I use Java EE annotation @Webservlet with a parameter name that is the same as the servlet’s. urlPatterns serve as the web link to invoke the URL of the Servlet and loadOnStartup, which then triggers the order of the Servlet; the smaller the number, the earlier it starts. | <br><br>I use Java EE annotation @Webservlet with a parameter name that is the same as the servlet’s. urlPatterns serve as the web link to invoke the URL of the Servlet and loadOnStartup, which then triggers the order of the Servlet; the smaller the number, the earlier it starts. | ||
<br><br> | <br><br> | ||
Next, I declare class variable alarmsNotifyObservable and override init method, so that when starting the Servlet, AslarmsRecevie.java can retrieve AlarmsNotifyObservable objects from Spring web context. Then in Service method, alarmsNotifyObservable receives and handles the information sent from Embedded System, calls the method of sendNotification(data) from AlarmNotifyObservable.java, and triggers Observable Pattern to notify the inherited Observer object. | Next, I declare class variable alarmsNotifyObservable and override init method, so that when starting the Servlet, AslarmsRecevie.java can retrieve AlarmsNotifyObservable objects from Spring web context. Then in Service method, alarmsNotifyObservable receives and handles the information sent from Embedded System, calls the method of sendNotification(data) from AlarmNotifyObservable.java, and triggers Observable Pattern to notify the inherited Observer object. | ||
− | + | <br><br><br>[[File:Private..png]] | |
<br><br>AlarmNotifyObservable.java is the Bean of Spring framework. | <br><br>AlarmNotifyObservable.java is the Bean of Spring framework. | ||
Using @Service in Spring framework to initiate AlarmNotifyObservable.java is to ensure that the whole system has only one Observable. AlarmNotifyObservable inherits the Observable of Java Util, to save those listeners and sends messages when the listeners are triggered. setChanged() means status change, while notifyObserver() represents the method of sending messages. | Using @Service in Spring framework to initiate AlarmNotifyObservable.java is to ensure that the whole system has only one Observable. AlarmNotifyObservable inherits the Observable of Java Util, to save those listeners and sends messages when the listeners are triggered. setChanged() means status change, while notifyObserver() represents the method of sending messages. | ||
<br><br> | <br><br> | ||
+ | [[File:Service.png]]<br><br> | ||
NetworkMapComposer.java mainly inherits ZK’s SelectorComposer and implements java.util.Observer. In NetworkMapComposer, it listens to the messages sent by Observer and uses ZK Server PUSH to update the information on UI immediately, and obtains the session-scope EventQueue. | NetworkMapComposer.java mainly inherits ZK’s SelectorComposer and implements java.util.Observer. In NetworkMapComposer, it listens to the messages sent by Observer and uses ZK Server PUSH to update the information on UI immediately, and obtains the session-scope EventQueue. | ||
− | <br><br>I use AlarmNotifyObservable to add myself into Observer pattern’s listening queue, and create an EventListener of Server Push. When Server Push changes the UI, (i.e. updateGis, initGis or openAlarmList) I use gisChangeEvent.subcribe (gisChangeEventEventListener) to subscribe to Server Push.<br><br> | + | <br><br>I use AlarmNotifyObservable to add myself into Observer pattern’s listening queue, and create an EventListener of Server Push. When Server Push changes the UI, (i.e. updateGis, initGis or openAlarmList) I use gisChangeEvent.subcribe (gisChangeEventEventListener) to subscribe to Server Push.<br><br>[[File:Gis.png]] |
NetworkMapComposer, which inherits java.util.Observer, implements update() method; this will influence updated items when Observer status is changed. | NetworkMapComposer, which inherits java.util.Observer, implements update() method; this will influence updated items when Observer status is changed. | ||
+ | <br>[[File:Gis.png]] | ||
=Challenges and Tips= | =Challenges and Tips= |
Revision as of 08:39, 7 March 2016
Vincent Feng, Engineer, Getech Technology Corporation
March 7, 2016
{{{version}}}
Foreword
I work as a software developer in an instrument company where we distribute and provide value-added services on solutions provided by Agilent, HP, Philips, etc. In this article I would like to share with you how I created a real-time system to both retrieve information from a remote embedded system and update the UI with ZK Server Push. I hope these tips will be useful references for those who have a similar requirement.
Functional Requirements
The system needs to listen to Http requests sent from the remote Embedded System, and update the information on ZK UI immediately, so that users can always get the latest update of the remote Embedded System.
I. System Structure
The system is mainly developed by Java EE, Spring, and ZK. I use Servlet in Java EE, accompanied by Observable Pattern to trigger ZK Server Push to change ZUL. The main classes and ZUL are named below:
Java EE Servlet 3.0 class:
Basically, AlarmsReceive.java is responsible for receiving Http requests from the Embedded System, and triggering ZK Server Push with Observable Pattern.
Spring Service Component class:
AlarmNotifyObservable.java inherits the class of java.util.Observable, delivers the information between Java EE and ZK, and notifies changes or updates of Observer object messages implemented in the system.
ZK Composer and ZUL:
NetworkMapComposer.java particularly inherits ZK’s SelectorComposer, and implements java.util.Observer. It listens to the events sent by Java EE through Observer, draws and updates UI.
NetworkMap.ZUL focuses on integrating NetworkMapComposer and finalizing UI.
II. Code Illustration
AlarmsReceive.java is Servlet 3.0.
I use Java EE annotation @Webservlet with a parameter name that is the same as the servlet’s. urlPatterns serve as the web link to invoke the URL of the Servlet and loadOnStartup, which then triggers the order of the Servlet; the smaller the number, the earlier it starts.
Next, I declare class variable alarmsNotifyObservable and override init method, so that when starting the Servlet, AslarmsRecevie.java can retrieve AlarmsNotifyObservable objects from Spring web context. Then in Service method, alarmsNotifyObservable receives and handles the information sent from Embedded System, calls the method of sendNotification(data) from AlarmNotifyObservable.java, and triggers Observable Pattern to notify the inherited Observer object.
AlarmNotifyObservable.java is the Bean of Spring framework.
Using @Service in Spring framework to initiate AlarmNotifyObservable.java is to ensure that the whole system has only one Observable. AlarmNotifyObservable inherits the Observable of Java Util, to save those listeners and sends messages when the listeners are triggered. setChanged() means status change, while notifyObserver() represents the method of sending messages.
NetworkMapComposer.java mainly inherits ZK’s SelectorComposer and implements java.util.Observer. In NetworkMapComposer, it listens to the messages sent by Observer and uses ZK Server PUSH to update the information on UI immediately, and obtains the session-scope EventQueue.
I use AlarmNotifyObservable to add myself into Observer pattern’s listening queue, and create an EventListener of Server Push. When Server Push changes the UI, (i.e. updateGis, initGis or openAlarmList) I use gisChangeEvent.subcribe (gisChangeEventEventListener) to subscribe to Server Push.
NetworkMapComposer, which inherits java.util.Observer, implements update() method; this will influence updated items when Observer status is changed.
Challenges and Tips
Note that if you are changing things like ZK UI components in ZK Server Push, it is not recommended that you send it through Server Push eventlistener, since during the sending process, server push will lock the sending object, and an error message will occur: Access denied: component. Therefore, those that will be changed should not be put into and sent by server push; instead, you should send values to indicate the changed UI content.
Complete example:
Caused by: java.lang.IllegalStateException: Access denied: component, <Rect mA3Qz3#RTU-T114_1>, belongs to another desktop: [Desktop z_hch:/security/template/baseLayout.zul]
1. Every time you re-enter SelectorComposer, UI will be re-drawn and a new SelectorComposer will be created. However, since the previous SelectorComposer may or may not be recycled yet, it will be difficult to define the actual time the SelectorComposer is created. To avoid such cases, when implementing update() method in Observer pattern, I first define whether the desktop exists already or not. If the desktop does not exist, it means that SelectorComposer does not exist either, and I can safely delete the invalid SelectorComposer in the observer pattern queue.
<template name="model">
<listitem value="${each}" item="@ref(self.value)">
As you can see, under the model template, I have filled the listitem's value with each, and I need to set a reference.
The binding doesn't work directly to the each object cause it's in a different lifecycle and by some strange behavior the each object is already gone before we can do the binding.
So a (hopefully temporarily) workaround is adding a reference : xxx="@ref(self.value)".
Like this we can do the binding to the xxx. You can choose the name for xxx.
This article is contributed by Vincent Feng for the community. Please feel free to leave him a comment below or create a discussion on ZK forum.
Comments
Copyright © Potix Corporation. This article is licensed under GNU Free Documentation License. |