package net.thesocialos.server.utils;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Properties;
import net.thesocialos.shared.messages.Message;
import com.google.appengine.api.channel.ChannelService;
import com.google.appengine.api.channel.ChannelServiceFactory;
import com.google.gwt.user.client.rpc.SerializationException;
import com.google.gwt.user.server.rpc.RPC;
public class ChannelServer {
private static Properties props = System.getProperties();
// private static final boolean USE_CHANNEL_API = setChannelAPIEnabled();
private static final String APP_KEY = "SOS-";
private static final Method dummyMethod = getDummyMethod();
/**
* Create a channel for a user. Returns the channel id that the client must use to connect for receiving push
* messages.
*
* @param userUniqueId
* @return the client channel id
*/
public static String createChannel(String userUniqueId) {
/*
* if(!USE_CHANNEL_API){ // logger.log(Level.WARNING,
* "Channel API disabled in appengine-web.xml. Not creating."); return null; }
*/
String channelId = getChannelService().createChannel(APP_KEY + userUniqueId);
// logger.info("Created new channel: " + channelId);
return channelId;
}
private static String encodeMessage(Message msg) {
try {
return RPC.encodeResponseForSuccess(dummyMethod, msg,
MergedSerializationPolicy.createPushSerializationPolicy());
} catch (SerializationException e) {
throw new RuntimeException("Unable to encode a message for push.\n" + msg, e);
}
}
private static ChannelService getChannelService() {
return ChannelServiceFactory.getChannelService();
}
private static Method getDummyMethod() {
try {
return ChannelServer.class.getDeclaredMethod("dummyMethod");
} catch (NoSuchMethodException e) {
throw new RuntimeException("Unable to find the dummy RPC method.");
}
}
public static void PushallUsers(List<String> userUniqueIds, Message msg) {
/*
* String encodedMessage = encodeMessage(msg); for (String userUniqueId : userUniqueIds) { String key =
* getAppKeyForUser(userUniqueId); //logger.info("Pushing msg to " + key); try {
* getChannelService().sendMessage( new ChannelMessage(key, encodedMessage)); } catch (Exception e) { // [The
* original google example code notes here: // A bug in the dev_appserver causes an exception to be // thrown
* when no users are connected yet.] // logger.log(Level.SEVERE, "Failed to push the message " + msg //+
* " to client " + key, e); } }
*/
}
/**
* Sends a message to one specific user.
*
* @param user
* The user to send the message to.
* @param msg
* The message to be sent.
*/
/*
* public static void pushMessage(User user, Message msg) { if (user.getChannelID() == null) {
* logger.log(Level.SEVERE,
* "Can't push a message to a null channeID. Maybe the Channel API is disabled in Connectr."); return; }
* pushMessageById(Arrays.asList(user.getEmail()), msg); } private static String getAppKeyForUser(String
* userUniqueId) { return APP_KEY + userUniqueId; } private static void pushMessageById(List<String> userUniqueIds,
* Message msg) { String encodedMessage = encodeMessage(msg); for (String userUniqueId : userUniqueIds) { String key
* = getAppKeyForUser(userUniqueId); //logger.info("Pushing msg to " + key); try { getChannelService().sendMessage(
* new ChannelMessage(key, encodedMessage)); } catch (Exception e) { // [The original google example code notes
* here: // A bug in the dev_appserver causes an exception to be // thrown when no users are connected yet.] //
* logger.log(Level.SEVERE, "Failed to push the message " + msg //+ " to client " + key, e); } } } private static
* boolean setChannelAPIEnabled() { String skey = props.getProperty("com.metadot.connectr.enable-channelapi"); if
* (skey != null) { if (skey.equalsIgnoreCase("true")) // logger.info("channel API is enabled"); return true; if
* (skey.equalsIgnoreCase("false")) return false; } return false; } // private static SerializationPolicy
* serializationPolicy = // MergedSerializationPolicy.createPushSerializationPolicy(); public ChannelServer() { }
* /** This method exists to make GWT RPC happy. <p> {@link RPC#encodeResponseForSuccess(java.lang.reflect.Method,
* Object)} insists that we pass it a Method that has a return type equal to the object we're encoding. What we
* really want to use is {@link RPC#encodeResponse(Class, Object, boolean, int,
* com.google.gwt.user.server.rpc.SerializationPolicy)} , but it is unfortunately private.
*/
@SuppressWarnings("unused")
private Message dummyMethod() {
throw new UnsupportedOperationException("This should never be called.");
}
}