Websocket Channel"

From Documentation
(Created page with "=Employment/Purpose= Since the release of ZK 8.0.0, it has supported a way to share the application data between ZK and non-ZK applications. Here we demonstrate how to use the <...")
 
Line 41: Line 41:
 
</syntax>
 
</syntax>
  
As you can see above, the line 2 we have to register a <javadoc>org.zkoss.zk.ui.http.ZKWebSocket</javadoc> class into the configurator of the server end point annotation.
+
As you can see above, in the line 2, we have to register a <javadoc>org.zkoss.zk.ui.http.ZKWebSocket</javadoc> class into the configurator of the ''ServerEndpoint'' annotation.
 
And in the line 10 we can use the method of <javadoc method="getDesktopStorage(javax.websocket.Session)">org.zkoss.zk.ui.http.ZKWebSocket</javadoc> to receive the data storage from a websocket session (the storage is a thread safe implementation). Note that the websocket session must have a '''dtid''' value which is sent from client as follows.
 
And in the line 10 we can use the method of <javadoc method="getDesktopStorage(javax.websocket.Session)">org.zkoss.zk.ui.http.ZKWebSocket</javadoc> to receive the data storage from a websocket session (the storage is a thread safe implementation). Note that the websocket session must have a '''dtid''' value which is sent from client as follows.
  
Line 50: Line 50:
  
 
=== ZK Application ===
 
=== ZK Application ===
Here is a MVVM example.
+
==== MVVM Example ====
 
<syntax lang="xml">
 
<syntax lang="xml">
 
<window id="win" apply="org.zkoss.bind.BindComposer"
 
<window id="win" apply="org.zkoss.bind.BindComposer"
Line 96: Line 96:
 
As you can see above, in the line 22 and 26, we can receive the data storage from the desktop object to share or update the application data into it, so that the websocket echo server can use or get the latest data from it or vise versa.
 
As you can see above, in the line 22 and 26, we can receive the data storage from the desktop object to share or update the application data into it, so that the websocket echo server can use or get the latest data from it or vise versa.
  
 +
==== MVC Example ====
 +
<syntax lang="xml">
 +
<window id="win" apply="org.zkoss.foo.ZKWebSocketComposer">
 +
        <groupbox title="ZK">
 +
            <hlayout>count: <label id="label" /></hlayout>
 +
            <button id="btn" label="add"/>
 +
        </groupbox>
 +
</window>
 +
</syntax>
 +
 +
<syntax lang="java" high="21,24,26">
 +
public class ZKWebSocketComposer extends SelectorComposer<Window> {
 +
@Wire Label label;
 +
@Wire Button btn;
 +
private Integer count;
 +
 +
@Override public void doAfterCompose(Window comp) throws Exception {
 +
super.doAfterCompose(comp);
 +
count = 100;
 +
label.setValue("100");
 +
syncToStorage();
 +
}
 +
 +
@Listen("onClick = #btn")
 +
public void doClick() {
 +
count++;
 +
label.setValue(String.valueOf(count));
 +
syncToStorage();
 +
}
 +
 +
private void syncToStorage() {
 +
getSelf().getDesktop().getStorage().setItem("count", count);
 +
}
 +
 +
@Command // this annotation is under the package of org.zkoss.zk.ui.annotation
 +
public void update() {
 +
count = getSelf().getDesktop().<Integer>getStorage().getItem("count");
 +
label.setValue(String.valueOf(count));
 +
}
 +
}
 +
</syntax>
 +
As you can see above, in the line 21 and 26, we can receive the data storage from the desktop object to share or update the application data into it, so that the websocket echo server can use or get the latest data from it or vise versa.
 +
 +
'''Note:''' in the line 24 <javadoc>org.zkoss.zk.ui.annotation.Command</javadoc> annotation has added since the release of ZK 8.0.0, and it is used to receive a notification from client to server. For more details, please have a look at the [[#Communication]] section.
 
=== Communication ===
 
=== Communication ===
 
==== From non-ZK (websocket) to ZK ====
 
==== From non-ZK (websocket) to ZK ====
 +
===== MVVM Example =====
 
Here is the MVVM way to send a command from client to server.
 
Here is the MVVM way to send a command from client to server.
 
<syntax lang="js">
 
<syntax lang="js">
Line 106: Line 151:
 
webSocket.onmessage = function(event) {
 
webSocket.onmessage = function(event) {
 
     zkbind.$('$win').command('update'); // the update command has already declared in ZKWebSocketViewModel.java
 
     zkbind.$('$win').command('update'); // the update command has already declared in ZKWebSocketViewModel.java
 +
};
 +
</syntax>
 +
===== MVC Example =====
 +
Here is the MVC way to send a command from client to server.
 +
<syntax lang="js">
 +
// Create a new instance of the websocket
 +
var webSocket = new WebSocket("ws://localhost:8080/zkwebsocket/echo/?dtid=" + zk.$('$win').desktop.uuid);
 +
 +
// receive a message from websocket, and notify ZK application to update the component data.
 +
webSocket.onmessage = function(event) {
 +
    zkservice.$('$win').command('update'); // the update command has already declared in ZKWebSocketComposer.java
 
};
 
};
 
</syntax>
 
</syntax>

Revision as of 06:37, 16 July 2015

Employment/Purpose

Since the release of ZK 8.0.0, it has supported a way to share the application data between ZK and non-ZK applications. Here we demonstrate how to use the Storage in a desktop scope to share the application data through the websocket channel.

Example

Non-ZK application (Websocket Server)

<syntax lang="java" high="2,10"> @ServerEndpoint(value ="/echo/", configurator = ZKWebSocket.class) public class EchoServer { @OnOpen public void onOpen(Session session) { }

@OnMessage public void onMessage(String message, Session session){ Storage<Integer> storage = ZKWebSocket.getDesktopStorage(session); if ("receive".equals(message)) { Integer count = storage.getItem("count"); try { session.getBasicRemote().sendText("Received..." + count); } catch (Exception e) { e.printStackTrace(); } } else { try { storage.setItem("count", Integer.parseInt(message)); session.getBasicRemote().sendText("Sent..." + message); } catch (IOException ex) { ex.printStackTrace(); } } } @OnClose public void onClose(Session session){ }

} </syntax>

As you can see above, in the line 2, we have to register a ZKWebSocket class into the configurator of the ServerEndpoint annotation. And in the line 10 we can use the method of ZKWebSocket.getDesktopStorage(Session) to receive the data storage from a websocket session (the storage is a thread safe implementation). Note that the websocket session must have a dtid value which is sent from client as follows.

<syntax lang="js"> // Create a new instance of the websocket var webSocket = new WebSocket("ws://localhost:8080/zkwebsocket/echo/?dtid=" + zk.$('$win').desktop.uuid); </syntax>

ZK Application

MVVM Example

<syntax lang="xml"> <window id="win" apply="org.zkoss.bind.BindComposer"

           viewModel="@id('vm') @init('org.zkoss.foo.ZKWebSocketViewModel')">
       <groupbox title="ZK">
           <hlayout>count: <label value="@load(vm.count)"/></hlayout>
           <button label="add" onClick="@command('cmd')"/>
       </groupbox>

</window> </syntax> <syntax lang="java" high="1,20,22,26"> @ToServerCommand("update") public class ZKWebSocketViewModel {

private Integer count;

@Init public void init(@ContextParam(ContextType.DESKTOP) Desktop desktop) { count = 100; syncToStorage(desktop); }

@Command @NotifyChange("count") public void cmd(@ContextParam(ContextType.DESKTOP) Desktop desktop) { count++; syncToStorage(desktop); }

@Command("update") @NotifyChange("count") public void doUpdate(@ContextParam(ContextType.DESKTOP) Desktop desktop) { count = desktop.<Integer>getStorage().getItem("count"); }

private void syncToStorage(Desktop desktop) { Storage<Integer> desktopStorage = desktop.getStorage(); desktopStorage.setItem("count", count); } public Integer getCount() { return count; } } </syntax> As you can see above, in the line 22 and 26, we can receive the data storage from the desktop object to share or update the application data into it, so that the websocket echo server can use or get the latest data from it or vise versa.

MVC Example

<syntax lang="xml"> <window id="win" apply="org.zkoss.foo.ZKWebSocketComposer">

       <groupbox title="ZK">
           <hlayout>count: <label id="label" /></hlayout>
           <button id="btn" label="add"/>
       </groupbox>

</window> </syntax>

<syntax lang="java" high="21,24,26"> public class ZKWebSocketComposer extends SelectorComposer<Window> { @Wire Label label; @Wire Button btn; private Integer count;

@Override public void doAfterCompose(Window comp) throws Exception { super.doAfterCompose(comp); count = 100; label.setValue("100"); syncToStorage(); }

@Listen("onClick = #btn") public void doClick() { count++; label.setValue(String.valueOf(count)); syncToStorage(); }

private void syncToStorage() { getSelf().getDesktop().getStorage().setItem("count", count); }

@Command // this annotation is under the package of org.zkoss.zk.ui.annotation public void update() { count = getSelf().getDesktop().<Integer>getStorage().getItem("count"); label.setValue(String.valueOf(count)); } } </syntax> As you can see above, in the line 21 and 26, we can receive the data storage from the desktop object to share or update the application data into it, so that the websocket echo server can use or get the latest data from it or vise versa.

Note: in the line 24 Command annotation has added since the release of ZK 8.0.0, and it is used to receive a notification from client to server. For more details, please have a look at the #Communication section.

Communication

From non-ZK (websocket) to ZK

MVVM Example

Here is the MVVM way to send a command from client to server. <syntax lang="js"> // Create a new instance of the websocket var webSocket = new WebSocket("ws://localhost:8080/zkwebsocket/echo/?dtid=" + zk.$('$win').desktop.uuid);

// receive a message from websocket, and notify ZK application to update the component data. webSocket.onmessage = function(event) {

   zkbind.$('$win').command('update'); // the update command has already declared in ZKWebSocketViewModel.java

}; </syntax>

MVC Example

Here is the MVC way to send a command from client to server. <syntax lang="js"> // Create a new instance of the websocket var webSocket = new WebSocket("ws://localhost:8080/zkwebsocket/echo/?dtid=" + zk.$('$win').desktop.uuid);

// receive a message from websocket, and notify ZK application to update the component data. webSocket.onmessage = function(event) {

   zkservice.$('$win').command('update'); // the update command has already declared in ZKWebSocketComposer.java

}; </syntax>