/*
* gw2live - GuildWars 2 Dynamic Map
*
* Website: http://gw2map.com
*
* Copyright 2013 zyclonite networx
* http://zyclonite.net
* Developer: Lukas Prettenthaler
*/
package net.zyclonite.gw2live.handler;
import java.util.Date;
import java.util.List;
import net.zyclonite.gw2live.model.ChatMessage;
import net.zyclonite.gw2live.model.Subscriber;
import net.zyclonite.gw2live.service.HazelcastCache;
import net.zyclonite.gw2live.service.MongoDB;
import net.zyclonite.gw2live.util.LocalCache;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.vertx.java.core.Handler;
import org.vertx.java.core.VoidHandler;
import org.vertx.java.core.buffer.Buffer;
import org.vertx.java.core.json.JsonObject;
import org.vertx.java.core.sockjs.SockJSSocket;
/**
*
* @author zyclonite
*/
public class SockJsHandler implements Handler<SockJSSocket> {
private static final Log LOG = LogFactory.getLog(SockJsHandler.class);
private static final int QUEUEMAXSIZE = 100;
private final List<Subscriber> subscribers;
private final HazelcastCache hcache;
private final MongoDB db;
public SockJsHandler() {
hcache = HazelcastCache.getInstance();
db = MongoDB.getInstance();
subscribers = LocalCache.SUBSCRIBER;
LOG.debug("SockJsHandler initialized");
}
@Override
public void handle(final SockJSSocket sock) {
LOG.debug("Handle connection " + sock.writeHandlerID());
sock.setWriteQueueMaxSize(QUEUEMAXSIZE);
final Subscriber subscriber = new Subscriber(sock.writeHandlerID(), hcache.getNodeId());
subscribers.add(subscriber);
sock.dataHandler(new Handler<Buffer>() {
@Override
public void handle(final Buffer inData) {
LOG.trace("got data");
final JsonObject json = new JsonObject(inData.getString(0, inData.length()));
final String messageType = json.getString("type");
if (messageType != null) {
switch (messageType) {
case "pve":
case "wvw":
case "channel":
try {
final JsonObject message = new JsonObject();
final String subscriptionId = json.getString("subscription_id");
if (messageType.equals("channel")) {
if (subscriptionId.matches("[0-9]+") && subscriptionId.length() == 13) {
final String nickname = json.getString("nickname");
if (nickname != null) {
subscriber.setNickname(nickname);
}
if (subscriber.getChannelId() != null) {
hcache.getChannelMap().remove(subscriber.getChannelId(), subscriber);
}
hcache.getChannelMap().put(subscriptionId, subscriber);
LOG.debug("added channel member " + subscriber.getConnection() + " to channel " + subscriptionId + " (membercount: " + hcache.getChannelMap().get(subscriptionId).size() + ")");
subscriber.setChannelId(subscriptionId);
message.putString("message", "success");
} else {
if (subscriber.getChannelId() != null) {
hcache.getChannelMap().remove(subscriber.getChannelId(), subscriber);
}
subscriber.setChannelId(null);
subscriber.setNickname(null);
message.putString("message", "unsubscribed");
}
} else {
subscriber.setSubscriptionId(subscriptionId);
message.putString("message", "success");
}
final JsonObject response = new JsonObject();
response.putString("type", "status");
message.putString("subscription_id", subscriptionId);
message.putString("type", messageType);
response.putObject("data", message);
final Buffer outData = new Buffer();
outData.appendString(response.encode());
sock.write(outData);
LOG.debug("subscribed to " + messageType + " " + subscriptionId);
} catch (Exception e) {
LOG.warn("Could not process subscription message!", e);
}
break;
case "chat":
try {
final ChatMessage chatmessage = new ChatMessage();
if (subscriber.getNickname() == null) {
chatmessage.setSender(subscriber.getConnection());
} else {
chatmessage.setSender(subscriber.getNickname());
}
chatmessage.setChannel(subscriber.getChannelId());
chatmessage.setMessage(json.getString("message"));
chatmessage.setIcon(json.getString("icon"));
try {
chatmessage.setX(json.getInteger("x"));
} catch (ClassCastException e) {
chatmessage.setX(0.0);
}
try {
chatmessage.setY(json.getInteger("y"));
} catch (ClassCastException e) {
chatmessage.setY(0.0);
}
chatmessage.setTimestamp(new Date());
hcache.getChatTopic().publish(chatmessage);
db.saveChatMessage(chatmessage);
LOG.debug("got chat message: " + chatmessage.getMessage() + " x=" + chatmessage.getX() + " y=" + chatmessage.getY() + " icon=" + chatmessage.getIcon() + " channel=" + chatmessage.getChannel());
} catch (Exception e) {
LOG.warn("Could not process chat message!", e);
}
break;
}
} else {
LOG.debug("message had no type flag");
}
}
});
sock.endHandler(new VoidHandler() {
@Override
public void handle() {
if (subscriber.getChannelId() != null) {
hcache.getChannelMap().remove(subscriber.getChannelId(), subscriber);
}
subscribers.remove(subscriber);
LOG.debug("removed connection " + sock.writeHandlerID());
}
});
}
}