GWT Integration

Table of Contents

GWT

Integration Overview

Client Perspective

The basic nature of GWT involves development of Java classes that are compiled into JavaScript for execution on the client. This means that GWT development with ICEpush closely mimics the basic [JavaScript Integration]. Low-level pushids and JavaScript callbacks are abstracted away in favor of event listeners and named push groups. The GWTPushContext provides the basic APIs for registering event listeners with notification groups.

A Command API is also available that provides a stream of command objects from the server to the client. This abstraction handles many of the complexities inherent to implementing a Command Pattern using the ICEpush protocol. For instance, commands are queued on the server and pulled in batches so as to avoid command loss. The Command Pattern API guarantees the delivery of any command placed on the queue (assuming the connection is healthy and the client is still running).

Server Perspective

At the server, GWT adheres to the standard Java Servlet model, and as such the basic Java EE Integration applies. Notification triggers are typically implemented within the GWT RemoteServiceServlet RPC.

Integration Basics

ICEpush integration with GWT involves two JAR libraries.

icepush.jar Common push API required for server initiated push.
icepush-gwt.jar The GWT integration classes and GWT module descriptor.

The GWT integration is an extension of the basic Java EE Integration. The server side of the integration uses org.icepush.PushContext class to create push ids, add group memberships and initiate push events. In most cases, group membership and push ids are abstracted from the developer, so calling these methods on the PushContext is not necessary. With respect to the client side of the integration, any third-party Java code must be "inherited" explicitly via the module configuration file - including the integration library itself. This is accomplished by adding "org.icepush.gwt.ICEpush" as an inherited module. To inherit the ICEpush library, simply add the following line to your module configuration file:

<inherits name="org.icepush.gwt.ICEpush"/>

The icepush.jar and icepush-gwt.jar then must included in the compile time and runtime classpath. After this, the classes can be used inside your project.

We include the icepush native javascript library into the module bootstrap html file:

    <!-- adding support for icepush -->
    <script type="text/javascript" src="code.icepush"></script>

And finally the ICEpush servlet component is added to the web.xml file:

    <!--icepush servlet-->
    <servlet>
        <servlet-name>icepush</servlet-name>
        <servlet-class>org.icepush.servlet.ICEpushServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>icepush</servlet-name>
        <url-pattern>*.icepush</url-pattern>
    </servlet-mapping>

Basic GWT Push API

Client-side APIs

Push Context

The class com.icesoft.icepush.integration.gwt.GWTPushContext provides a singleton client-side push context that can be used to programatically react to push events that are generated on the server. It provides following API:

com.icesoft.icepush.integration.gwt.GWTPushContext
public static GWTPushContext getInstance();
public void addPushEventListener(PushEventListener listener, String groupNames);
public void removePushEventListener(PushEventListener listener);

Please see the related JavaDoc for more information regarding the use of each of these methods.

Push Event Listener

The class com.icesoft.icepush.integration.gwt.PushEventListener provides an abstract base class for push event listeners. It provides following API:

com.icesoft.icepush.integration.gwt.PushEventListener
public void onPushEvent();

An example listener might be:

org.icepush.demo.MyListener
public class MyListener extends PushEventListener{
   public void onPushEvent(){
      Window.alert("Notification Received!!!");
   }
}

This listener would simply popup the message "Notification Received" when the listener is triggered

Push Event Registration

Client-side push event registration is achieved using the GWTPushContext.addPushEventListener() method. Continuing with the previous example:

GWTPushContext context = GWTPushContext.getInstance();

context.addPushEventListener(new MyListener(), new String("myGroup"));

This will cause the popup when "myGroup" is pushed to.

Notification

Currently, client initiated push events are not permitted. All push notifications must originate from the server. As typically notification triggers are associated with some server-side state change, this does not represent a major obstacle. Simply place calls to the PushContext in RemoteService servlets (or any other server-side component) and the push events will be received on the client.

For more information on server initiated push in GWT see the next section.

Server-side APIs.

Push Context

The standard ICEpush Java EE Integration APIs are used to access and manipulate the PushContext from server-side logic. This logic is typically implemented within the GWT RemoteServiceServlet Remote Procedure Call, as illustrated below.

public class MyServiceImpl extends RemoteServiceServlet{
    public void myMethod(){
        //the following lines can be added to any Remote GWT service.

        PushContext context = PushContext.getInstance(this.getServletContext());
        context.push("newgroup");
    }
}

GWT Command Push API

As previously mentioned, the ICEpush GWT integration also provides developers with a Command Pattern API. This API abstracts out much of the complexity involved with queuing and delivering commands using the lower-level GWT integration API.

Client-side APIs

The client side aspect of the Command API consists of three basic items: the ClientPushCommandContext controller class, the ICommand interface and the ICommandExecutor interface.

The ICommand is the simplest so lets start with that. The ICommand interface is a marker interface that is used by ICEpush to identify a command POJO. A Command in the API is simply a POJO that implements the ICommand interface. Note that commands are serialized by GWT and thus must implement java.io.Serializable and not utilize any unsupported libraries. Other than that - the Command is simply a POJO. An example command is shown below:

public class ParticipantEntryCommand implements ICommand,Serializable{

	private String participantName;

	public String getParticipantName() {
		return participantName;
	}

	public void setParticipantName(String participantName) {
		this.participantName = participantName;
	}
}

Next lets discuss the ICommandExecutor interface. Command Executors are invoked by the framework when a command is received from the server. One of the guarantees of the API is that a command executor will be invoked for every command that is placed on the server queue. Thus developers do not need to worry about the lower-level details of the ICEpush protocol. Implementors of the ICommandExecutor interface need to provide one method:

public void execute(ICommand command);

This method will get invoked for each command received by the client. Continuing for the previous example, a command executor for the ParticipantEntryCommand might look as follows:

public class ParticipantEntryCommandHandler implements ICommandExecuter {

	public void execute(ICommand command) {
		ParticipantEntryCommand castedCommand = 
                     (ParticipantEntryCommand) command;
		//perform action based on the data in the command
                Window.alert(castedCommand.getParticipantName());
	}
}

Now the only remaining client-side step is to actually associate this command executor with the specific command type. The ClientPushCommandContext class is responsible for maintaining the command registry. Please view the JavaDoc for this class on information on the features this controller provides. Most notable there are two methods defined that every GWT Command Application will need to use:

public void registerExecuter(Class<? extends ICommand> commandClass,
                             ICommandExecuter handler);

and

public void deregisterExecuter(Class<? extends ICommand> commandClass,
                               Class< ? extends ICommandExecuter> handler)

To complete the previous example, the ParticipantEntryCommand can be registered to the ParticipantEntryCommandExecutor via the following line of code:

context.registerExecuter(ParticipantEntryCommand.class,
                         new ParticipantEntryCommandHandler());

As soon as the registerExecutor() method is used to tie a handler to a command, that handler will be called for any command of that class that is received.

Server-side APIs

The server side of the Command API is very simple. It consists of a singleton ServerPushCommandContext which is tied to the Servlet context. Commands can be created and queued into the ServerPushCommandContext, and they will be streamed to the appropriate clients.

The ServerPushCommandContext can be fetched via the ServerPushCommandContext.getInstance(ServletContext context) method.

The pushCommand() method can then be used to place a command on the queue.

for example:

    ParticipantEntryCommand command = new ParticipantEntryCommand();
    command.setParticipantName(input);
    ServerPushCommandContext.getInstance(getServletContext()).
                             pushCommand(command, getServletContext());

Tutorial

A tutorial on extending the example "Greeting" GWT application can be found here.

Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.

© Copyright 2017 ICEsoft Technologies Canada Corp.