Help with IPC add-on

OK so I have been trying to get the IPC add-on to work now for a few days and I have ran out of options.

To create my project I am using eclipse, the step I took are:

  1. Created a new vaadin project with servlet 3.0 and portlet 2.0.
  2. Added my 2 portlets information into the required XML files for liferay and such.
  3. Added the ipc plugin 0.91 to the project and vaadin asked to me to rebuild widget set, which I said yes.
  4. Made 2 new simple UI’s for the 2 portlets, one being the receiver one being the sender.
  5. Export war file from eclipse and drag it into liferay.
  6. Portlets show up fine and I dont get any missing debug statements on the tomcat server.

The way the portlets are configured I have a notification when the event is fired and one when the event is received. The notification pops up when the event is fired but does nothing shows up to show it was received. Now I have imported the sample rar that came inside the IPC package and that works fine but I am unable to see what it is doing differently.

Here are the relevant portions of code:

Sender code:


	ipc.sendEvent("update", "Updated: " + l.getValue());
	hWnd.showNotification("Event dispatched: Updated: " + l.getValue());

Receiver code:


	ipc.addListener("update", new IPCListener());

	private class IPCListener implements LiferayIPCEventListener
	{
		public void eventReceived(LiferayIPCEvent event) 
		{	
			hWnd.showNotification("Got event "+event.getEventId()+" with data "+event.getData());
			main.removeAllComponents();
		}
	}

Am I missing anything here?

Thanks,
Justin

Did you add the IPC objects to a layout? Check out the demo source: http://dev.vaadin.com/svn/addons/IPCforLiferay/trunk/demo/src/com/vaadin/addon/ipcforliferay/demo/

The problem I’m having is that the event fires as expected, but the receiving LiferayIPC object never gets repainted.

So in my Sending class (pseudocode):


Window main = new Window();
VerticalLayout layout = new VerticalLayout();
LiferayIPC ipc = new LiferayIPC();
ipc.sendEvent("eventID", "Populating Live Table");
layout.add(ipc);
main.add(layout);

In my Receiving class:


Window main = new Window();
VerticalLayout layout = new VerticalLayout();
LiferayIPC ipc = new LiferayIPC();
ipc.addListener("eventID", new LiferayIPCEventListener() { ... });
layout.add(ipc);
main.add(layout);

The event fires and calls sendEvent() in LiferayIPC.class


public void sendEvent(String eventId, String data) {
		pendingEventIds.add(eventId);
		pendingEventData.add(data);
		requestRepaint();
	}

So now my receiving component has a pending event and is just waiting for the repaint to occur. The issue I’m facing is that my portlet code currently removes all components and adds them from scratch on refresh, i.e. that pending event is lost because the listener is added from scratch, too. So I’m looking into refactoring that. Perhaps your portlet is doing something similar and this pending event is being lost.

Got it working when I re-wrote the component. Component creates a layout, creates an element which fires IPC events, and attaches both the element and an IPC listener to the layout. Add the layout to the window and sha-zam, functional IPC-enabled portlet that sends and receives IPC events. I tested it with the demo war that came with the add-on and watching the crosstalk was a beautiful thing.


public class DevicesPortlet extends Application implements PortletListener{

LiferayIPC liferayIPC = new LiferayIPC();

	@Override
	public void init() {
		Window mainWindow = new Window("Device Portlet");
		
		setMainWindow(mainWindow);
		
		/*
		 * Set listener
		 */
		if (getContext() instanceof PortletApplicationContext2) {
			((PortletApplicationContext2) getContext()).addPortletListener(this, this);
		} else {
			System.out.println("Portlet error");
		}
		
	}

@Override
	public void handleRenderRequest(RenderRequest request,
			RenderResponse response, Window window) {

if(!window.getComponentIterator().hasNext())
		{
                        VerticalLayout deviceTableContainer = new VerticalLayout();
			deviceTableContainer.addComponent(createDeviceTable());
			liferayIPC.setImmediate(false);
			liferayIPC.setWidth("-1px");
			liferayIPC.setHeight("-1px");
			liferayIPC.addListener("newPerson", new LiferayIPCEventListener() {
				public void eventReceived(LiferayIPCEvent event)
				{
					log.info("IPC event received!");
				}
			});
			deviceTableContainer.addComponent(liferayIPC);
			window.addComponent(deviceTableContainer);
}
		}
	}

private Table createDeviceTable(String portletEmail, String portletSession)
	{
		Table deviceTable = new Table();
/* ... code to populate Table ... */
		ValueChangeListener projectDeviceTableListener = new Table.ValueChangeListener() {
			public void valueChange(ValueChangeEvent event) {
				//fire IPC event for other portlets to update
				
				liferayIPC.sendEvent("newPerson", "fname;lname;15");				
			}
		};
		
		deviceTable.addListener(projectDeviceTableListener);
		
		return deviceTable;
	}

I worked today the whole day on the problem of IPC. I tried different approaches after I failed with this addon.

But then there came the solution:

you have to add the LiferayIPC as component to a displayed window.

Every demo code omits that single line!

Just a small line

addComponent(ipc)

or event

someWindow.addComponent(ipc)

would have helped me to save at least half a day.

Perhaps this small post may help somebody in the same situation I am. And perhaps the docu gets updated to include that line :-).

bye,
Roland