Hi All,
this is my pattern of how I implement comet.
I may change how I handle the ArrayListMessage or use a timestamp as
parameter of get method, but basically I always start from this
simple snippet of code.
It's for GWT but I've basically used it also in a Web Service and in a
REST service.
hope it's useful:
---
- GWT RPC Service interface -
package net.cristcost.test.comet.client;
import java.util.List;
import com.google.gwt.user.client.rpc.RemoteService;
public interface MessageBus extends RemoteService {
public void publish(Message msg);
public ListMessage get(int last);
}
---
- GWT RPC Service Implementation -
package net.cristcost.test.comet.server;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import net.cristcost.test.comet.client.Message;
import net.cristcost.test.comet.client.MessageBus;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@SuppressWarnings(serial)
public class MessageBusImpl extends RemoteServiceServlet implements
MessageBus {
private ArrayListMessage messages;
public MessageBusImpl() {
messages = new ArrayListMessage();
}
@Override
synchronized public ListMessage get(int lastIndex) {
try {
int lastMessage = messages.size() - 1;
if (lastIndex = lastMessage) {
// wait for new message to arrive
wait(3);
}
ArrayListMessage ret = new ArrayListMessage();
for (int i = lastIndex + 1; i messages.size(); i++) {
ret.add(messages.get(i));
}
return ret;
}
catch (InterruptedException e) {
return null;
}
}
@Override
synchronized public void publish(Message msg) {
msg.setTime(new SimpleDateFormat(h:mm:ss.SSS).format(new
Date()));
messages.add(msg);
notifyAll();
}
}
---
- Publish sample usage (in UiBinder) -
@UiHandler(msgBtn)
void handleClick(ClickEvent e) {
mb.publish(new Message(msgTextBox.getText(),
DateTimeFormat.getFormat(h:mm:ss.SSS).format(new Date())),new
AsyncCallbackVoid(){
@Override
public void onFailure(Throwable arg0) {
Window.alert(Message publication failed);
}
@Override
public void onSuccess(Void arg0) {
// nothing to do
}});
}
---
- Consumer example (in UiBinder) -
package net.cristcost.test.comet.client;
import java.util.Date;
import java.util.List;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Widget;
public class Subscribe extends Composite {
interface SubscribeUiBinder extends UiBinderWidget, Subscribe {
}
private static SubscribeUiBinder uiBinder =
GWT.create(SubscribeUiBinder.class);
@UiField
Label endPoint;
@UiField
FlowPanel list;
@UiField
Button startStopBtn;
private int lastUpdate;
private boolean isSubscribed;
private MessageBusAsync mb = GWT.create(MessageBus.class);
public Subscribe() {
initWidget(uiBinder.createAndBindUi(this));
lastUpdate = -1;
isSubscribed = false;
}
private void getUpdates() {
mb.get(lastUpdate, new AsyncCallbackListMessage() {
@Override
public void onFailure(Throwable arg) {
startStopBtn.setText(wait);
startStopBtn.setEnabled(false);
isSubscribed = false;
handleUpdates(null);
}
@Override
public void onSuccess(ListMessage newMessages) {
handleUpdates(newMessages);
}
});
}
private void handleUpdates(ListMessage msgList) {
if (msgList != null) {
String displayTime =
DateTimeFormat.getFormat(h:mm:ss.SSS).format(new Date());
for (Message m : msgList) {
list.add(new Label(Msg: ' + m.getMsg() + ',
published at + m.getPubTime()
+ , stored on server at + m.getTime() + ,
displayed at + displayTime +
of + msgList.size() + messages));
}
lastUpdate += msgList.size();
}
if (isSubscribed) {