ICEPush add-on

ICEPush is an add-on for enabling server side push in Vaadin applications. Using server side push you can update the application at any time and not only as a reaction to what the user does.

It is useful for long running background threads: show “please wait” to the user, do a long running process in the background and replace the “please wait” with real data once the process is finished. For an example of this, see the really simple demo at
http://artur.virtuallypreinstalled.com/ICEPushDemo/
(no polling is done, an event is sent when the process has finished)

It is also useful for communication between users. You can update the application of a user as a reaction to what another user does. A simple example of this would be a chat, see a simple demo at
http://artur.virtuallypreinstalled.com/ICEPushChat/
. Another example is the multi user calendar at
http://artur.virtuallypreinstalled.com/MultiUserCalendar/

It can be used also for portlets and for communication between portlets: e.g. update one portlet as a reaction to what happens in the other, without needing a refresh or polling. (The communication mechanism is not provided by the add-on, only the push mechanism).

The current version of the ICEPush add-on is 0.2.0 and is
available from the Directory
. It is still experimental, mainly because the ICEPush library it depends on is an alpha version. There are no known bugs or problems.

Hi, I just upgraded from 0.1.2 to 0.2.0 and am having two issues:

  1. ICEPushServlet is throwing a NullPointerException from line 52 where request.getPathInfo() is used. I think it’s because getPathInfo() would return null when the request url doesn’t end in ‘/’. I fixed it by changing the line to:

     if (("/" + javascriptProvider.getCodeName()).equals(request.getPathInfo())) {
    
  2. No pushes happen any more. I don’t see the periodic icepush requests to the server that I used to see with 0.1.2. One thing I noticed is that the client no longer requests icepush.js. It seems intentional from the code history, so are there any changes I need to make for my application to work again with 0.2.0?

Thanks for any advices.
-jx

That would be a bug. Actually had it fixed in my workspace but it has not ended up in 0.2.0 for some reason.

It no longer requests icepush.js, instead it dynamically loads “code.icepush” from the server (which basically is the same thing except it gets a bit rewritten by the servlet). It should not require you to make any changes, however. The easiest way to figure out what goes wrong is probably to use Firebug and check what requests are sent and if there is an error in one of the requests.

The requests should be

  • GET code.icepush
  • POST create-push-id.icepush
  • POST add-group-member.icepush
  • POST listen.icepush

Thanks for the quick response.

I see the first three in Firebug, without any apparent errors in the responses, however I don’t see a request for listen.icepush.

-jx

Kinda hard to guess what could be wrong. http://artur.virtuallypreinstalled.com/MultiUserCalendar uses ICEPush 0.2.0 so maybe you could compare with what responses it sends and what is logged to the Firebug console to get a hint of what possibly goes wrong.

OK, I’ve been able to reduce it to a simple scenario - it works only if the ICEPushServlet is specified with the match-all mapping. IOW, this works just fine:


  <servlet-mapping>
  	<servlet-name>Test Application</servlet-name>
  	<url-pattern>/*</url-pattern>
  </servlet-mapping>

but this won’t:


  <servlet-mapping>
  	<servlet-name>Test Application</servlet-name>
  	<url-pattern>/main/*</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>Test Application</servlet-name>
    <url-pattern>*.icepush</url-pattern>
  </servlet-mapping>

In the later case the client somehow never sends out the listen.icepush request.

-jx

Hi Artur,

As discussed yesterday over Skype, I am scratching my head for hours now trying to figure out how to use the Add on in an application where the user goes from one window to another.

I have simplified my example to the max. It is based on the excellent
SpringSecurityDemo
and I apologize to the author for slaughtering his code.

The GigHub repository for the code is
here
.
The two main classes are
ICEPushCaseApp
and
HomeView
.

Basically, when the user authenticates, there’s a button on the Home Screen which just calls pusher.push on the main application. This however generates an exception and the push mechanism is broken. However the pusher does work indeed in the first screen (although it isn’t demonstrated here).

I have tried pretty much every combination that I could come up with and have found no solution to my problem. From what I can see there is thus no way to take advantage of push in a secured application.

Please prove me wrong.

Cheers,

Candide

Hi Arthur,

Great add-on and seems to work great. However, I have compiled the sources with 1.5 compatibility because I was getting class version errors in production (which runs JDK5). Sounds familiar?

Is it possible to create a 1.5 compatible jar?

Regards,
Jamie

Hello Arthur, I am new to Vaadin as well as Java. I wish to code a simple chat application just like the one that is available on addon page http://artur.virtuallypreinstalled.com/ICEPushChat/ . Could you please upload the source code for pushchat? That would be much helpful.

Thanks.

P.S. I have been trying to get in touch with you for some time now. Apparently you can’t send personal messages at forums as well as addon-directory.

Hi,

If I remember correctly my own code it assumes the ICEPushServlet is available at context/.icepush which means you need to map it to / to work correctly. You can use the older version to get around this as it does not figure out what url to use automatically, instead just uses the current url and adds the *.icepush to it (this is the reason the url always needs to end in a /)

Hi,

Seems I have forgot to set the workspace to use JDK 1.5. Will try to remember that for the next version.

Hi,

The chat application is not very good example code but I will add it to github once I get the chance.

Hello,
since the new version 0.2.0, indeed the servlet is no more called.
Firebug’s network inspect highlights a 404 error for “http://localhost:8080/code.icepush
That is really weird, since the vaadin context URL is “http://localhost:8080/vaadin-sampler

I guess the last feature/fix removing the last “/” char from the URL brought a huge regression.

Thanks

Hi Artur Signell :

The MultiUserCalendar demo is a good push example, When the chart position changed another browser will receive the notify message.

So i write another my push example use icepush-addon, But it does not work, the code is below. It only refersh current browser, another browser or session
don’t
have any changed!

So ,what is wrong ? Please help me, Thanks!

public class ApplicationPush extends Application {

private final static Logger logger = LoggerFactory.getLogger( ApplicationPushController.class );
private Window loginWindow = null;
private ICEPush pusher = new ICEPush();
Label label = new Label( "-------" );

public ApplicationPushController() {
}

public void init() {
	logger.info( "Starting build login window..." );

	VerticalLayout layout = new VerticalLayout();
	
	// Create main Window
	loginWindow = new Window( "Hello" , layout );
	loginWindow.setName( "Main" );
	
	//
	setMainWindow( loginWindow );

	/**
	 *
	 */
	Button startButton = new Button( "Start" );
	startButton.addListener( ClickEvent.class , this , "startUpdate" );

	layout.addComponent( startButton );
	layout.addComponent( pusher );
	layout.addComponent( label );

	//
	logger.debug( "Current main window is...{}|{}" , loginWindow.getName() , loginWindow );
}

private int i = 0;

public void startUpdate(ClickEvent event) {

	logger.debug( "Start update..." );
	
	label.setValue( "zzz-->" + i );
	label.requestRepaint();

	/**
	 *
	 */
	pusher.push();
	
	i++;
}	

}:):):):):*)

The UI for second browser needs to do its own push so that the second browser gets updated. You are apparently only pushing changes in the application that did the change. Pushing means “get the current browser updated” – NOT “get all the browsers updated”.

The typical way this is done is using an Event. All your applications that need to refresh must subscribe as listeners to an event. When an application updates the data, it sends an event to all the listeners. In the event listener, the UI for each of the listening apps is updated, and the pusher for THAT application is called.

See the Blackboard add-on for an easy to use event dispatching mechanism.

Hi:

I know every application only push itself. Firstly two browser means two application instance in vaadin, i use thread sync and wait, but it is wrong, always only one application instance can push itself, all others application can not push.

So, compare multi-thread sync & wait with event listener, I think they are all can do.

Importantly when i use a back-end thread which not start from any application instance send message to all application, It is wrok !!!

When i use one application send message to all others application instance, only one application can push itself, They are
didn’t
work !!!

So, Why ?

I write another push example using event listener to notify every application, It works fine!

But i didn’t known why use multi-thread sync & wait they didn’t push ?!

I think the cause is as follows: In a servlet container the thread is started when the server gets an HTTP request, which calls the service method from the servlet. So there is one servlet class, but many threads, one per request. I don’t understand how your thread meeting approach would work – there is nothing that keeps running for a given HTTP session between requests. This is why we need sessions – there is no thread that just sits there and maintains state.

So if you have several browsers that are waiting, there is NO active thread in the server for that browser (other than the container waiting for connections). If I understand how ICEPush works, all it does is keep a single connection open to the browsers that connected through the PushServlet.

So when you are pushing because something happened, there is only ONE thread that is doing all the work of calling push() for all the browsers. It is the original thread that received the http request (or a thread that was forked from that). All that push() does (as far as I can tell) is write a command to the browser on an open connection.

Hi:

Thanks for you suggestion and analysis again, I think the ICEPush implementation is the key point, So i need to read it and verify my test case.

Regards!

Hi Artur,

First of all, thank you for this useful add-on. I created my own chat application implementation using this and it works great. You can find it here: http://chat.rbbelen.staxapps.net/

However I found one problem with this add-on when using IE. It works fine for standalone applications but when I embedd a vaadin application that uses this add-on to another HTML page (using iframe), it doesn’t seem to work correctly.

For example, this web page works fine in other browsers but not in IE.

http://rowellbelen.com/content/sample-vaadin-chat-application

Thanks!

Rowell