package gwtgaetools.client.comm;
import gwtgaetools.shared.model.GenericMessage;
import com.google.gwt.appengine.channel.client.Channel;
import com.google.gwt.appengine.channel.client.ChannelFactory;
import com.google.gwt.appengine.channel.client.ChannelFactory.ChannelCreatedCallback;
import com.google.gwt.appengine.channel.client.Socket;
import com.google.gwt.appengine.channel.client.SocketError;
import com.google.gwt.appengine.channel.client.SocketListener;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.SerializationException;
import com.google.gwt.user.client.rpc.SerializationStreamFactory;
import com.google.gwt.user.client.rpc.SerializationStreamReader;
/**
* Client-side rpc class for client-server communication
* @author opowell
*
*/
public abstract class GenericClientRPC<
Type,
MainObject,
RPCService extends GenericRPCServiceAsync<Type, Message>,
Message extends GenericMessage<Type>,
MessageInterpreter extends GenericMessageInterpreter<Type, Message, ?>
> {
private MessageInterpreter interpreter;
public Socket socket;
public String channelToken;
public String clientId;
public MainObject dataModel;
public RPCService rpcService;
protected AsyncCallback<Void> emptyCallback = new AsyncCallback<Void>() {
@Override
public void onFailure(Throwable caught) {}
@Override
public void onSuccess(Void result) {}
};
public GenericClientRPC(MainObject m) {
dataModel = m;
interpreter = createInterpreter();
rpcService = createRPCService();
}
protected abstract MessageInterpreter createInterpreter();
protected abstract RPCService createRPCService();
// Default: do nothing.
public void reset() {}
// public void askForChannelToken(final String traderID) {
// rpcService.askForChannelToken(traderID, new AsyncCallback<ArrayList<String>>() {
//
// @Override
// public void onFailure(Throwable caught) {
// System.out.println("GenericClientRPC.askForChannelToken(): error " + caught);
// }
//
// @Override
// public void onSuccess(ArrayList<String> results) {
// channelToken = results.get(0);
// createChannel(results.get(0), results.get(1), traderID);
// }
//
// });
// }
public void onSocketOpen(String cId) {
System.out.println("Channel opened!");
clientId = cId;
}
public void onSocketClose() {
System.out.println("Channel closed! Asking for new token...");
reconnectChannel();
}
public void createChannel(final String channelToken, final String cId) {
if (socket!=null)
socket.close();
this.channelToken = channelToken;
ChannelFactory.createChannel(channelToken, new ChannelCreatedCallback() {
public void onChannelCreated(final Channel channelResult) {
socket = channelResult.open(new SocketListener() {
public void onOpen() {
onSocketOpen(cId);
}
public void onMessage(final String encodedData) {
try {
// SerializationStreamReader reader = ((SerializationStreamFactory)rpcService).createStreamReader(encodedData);
// @SuppressWarnings("unchecked")
// ArrayList<Message> messages = (ArrayList<Message>) reader.readObject();
// for (Message message : messages)
SerializationStreamReader reader = ((SerializationStreamFactory)rpcService).createStreamReader(encodedData);
@SuppressWarnings("unchecked")
Message message = (Message) reader.readObject();
processMessage(message);
} catch (SerializationException e) {
throw new RuntimeException("Unable to deserialize " + encodedData, e);
}
}
public void onError(SocketError error) {
channelError(error);
}
public void onClose() {
onSocketClose();
}
});
}
});
}
public void channelError(SocketError error) {
System.out.println("Error: " + error.getDescription());
}
public abstract void reconnectChannel();
public void processMessage(Message s) {
try {
interpreter.processMessage(s);
} catch (Exception e) {
e.printStackTrace();
}
}
public AsyncCallback<Void> getEmptyCallback() {
return emptyCallback;
}
public void sendMessage(Message msg) {
sendMessage(msg, emptyCallback);
}
public void sendMessage(Message msg, AsyncCallback<Void> ascb) {
rpcService.processMessage(msg, ascb);
}
}