Introduction

In ZK 8.5, there is a new session, where a WebSocket-based update engine is introduced to handle requests if the browser is supported.

The advantage of WebSocket (over AJAX), is once the connection has been established, all future messages are passed over the socket rather than new HTTP request/response calls. The ping and pong messages will be smooth and also save traffic!

We support not only WebSocket-based Update Engine, but also a WebSocket-based server push. This reduces the count of http connections when there is a huge amount of updates.

WebSocket Demo

In the first clip, we can see when the ajax-based ZK update engine is on, numerous requests will be established. While in the second clip, with websocket based ZK update engine, there is only one connection established; even if we enable server push, less HTTP overhead.

Required Configuration

Versions:

  • ZK: 8.5.0.FL.20170725-Eval or later
  • Browser: Internet Explorer 10+, Edge, Firefox, Chrome, Safari, iOS Safari, Android Browser, Opera

zk.xml

<!-- required -->
<listener>
	<listener-class>org.zkoss.zkmax.au.websocket.WebSocketWebAppInit</listener-class>
</listener>

<!-- optional -->
<library-property>
	<name>org.zkoss.zkmax.au.websocket.WebSocketEndPoint.urlPattern</name>
	<value>/myappws/</value>
</library-property>
    • Line 2 to 4: It is required to add a configuration org.zkoss.zkmax.au.websocket.WebSocketWebAppInit to enable the WebSocket connection.
    • Line 6 to 9: Map the url pattern for WebSocket connection; if this library property is not configured, /zkwm will be used by default.

Be noted that WebSocketServerPush will be the selected server push class if the WebSocket connection is on, even though other server push class is configured in zk.xml.

Downloads

The whole demo project can be found on Github project.

If you enjoyed this post, please consider leaving a comment or subscribing to the RSS feed to have future articles delivered to your feed reader.

5 Responses to “ZK 8.5 Preview: Built in WebSocket Communication is Now Provided”

  1. Costas Yiannoulis says:

    I can’t wait to see this feature!

  2. Vincent Lee says:

    Is there any thing special required for the app server to support this?

  3. Hawk says:

    @Vincent Lee
    websocket API (JSR 356) is a part of Java EE 7 standard. (http://www.oracle.com/technetwork/articles/java/jsr356-1937161.html) So all Java EE 7–compliant application servers will have an implementation of the WebSocket protocol that adheres to the JSR 356 standard e.g. Tomcat 7 (refer to https://antoniogoncalves.org/2016/02/02/o-java-ee-7-application-servers-where-art-thou/)

  4. fenrir says:

    have nullpoint in WebSocketWebAppInit:

    java.lang.NullPointerException
    at org.zkoss.zkmax.au.websocket.WebSocketWebAppInit.init(WebSocketWebAppInit.java:60)
    at org.zkoss.zk.ui.util.Configuration.invokeWebAppInits(Configuration.java:779)
    at org.zkoss.zk.ui.impl.AbstractWebApp.init(AbstractWebApp.java:214)
    at org.zkoss.zk.ui.http.SimpleWebApp.init(SimpleWebApp.java:58)
    at org.zkoss.zk.ui.http.WebManager.(WebManager.java:235)
    at org.zkoss.zk.ui.http.HttpSessionListener23.contextInitialized(HttpSessionListener23.java:141)
    at org.eclipse.jetty.server.handler.ContextHandler.startContext(ContextHandler.java:740)
    at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:238)
    at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1238)
    at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:683)
    at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:480)
    at org.mortbay.jetty.plugin.JettyWebAppContext.doStart(JettyWebAppContext.java:256)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:64)
    at org.eclipse.jetty.server.handler.HandlerCollection.doStart(HandlerCollection.java:229)
    at org.eclipse.jetty.server.handler.ContextHandlerCollection.doStart(ContextHandlerCollection.java:172)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:64)
    at org.eclipse.jetty.server.handler.HandlerCollection.doStart(HandlerCollection.java:229)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:64)
    at org.eclipse.jetty.server.handler.HandlerWrapper.doStart(HandlerWrapper.java:95)
    at org.eclipse.jetty.server.Server.doStart(Server.java:275)
    at org.mortbay.jetty.plugin.JettyServer.doStart(JettyServer.java:65)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:64)
    at org.mortbay.jetty.plugin.AbstractJettyMojo.startJetty(AbstractJettyMojo.java:511)
    at org.mortbay.jetty.plugin.AbstractJettyMojo.execute(AbstractJettyMojo.java:364)
    at org.mortbay.jetty.plugin.JettyRunMojo.execute(JettyRunMojo.java:521)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:137)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:210)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:156)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:148)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:117)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:81)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:56)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:305)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:192)
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:105)
    at org.apache.maven.cli.MavenCli.execute(MavenCli.java:956)
    at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:288)
    at org.apache.maven.cli.MavenCli.main(MavenCli.java:192)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:282)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:225)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:406)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:347)
    at org.codehaus.classworlds.Launcher.main(Launcher.java:47)

  5. Robert Wenzel says:

    @fenrir: it looks like your jetty configuration is missing the websocket module

    However this comment section of our blog is not a good place to start such a discussion/debugging thread.
    Please either refer to our support or ask your question in our forum

    Also please never forget to mention your ZK version and in this case Jetty version, and if possible provide all the configuration required to reproduce the error message.

    https://www.zkoss.org/support/
    https://forum.zkoss.org/

Leave a Reply