Skip to content

Instantly share code, notes, and snippets.

@macnibblet
Created July 12, 2013 10:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save macnibblet/5983426 to your computer and use it in GitHub Desktop.
Save macnibblet/5983426 to your computer and use it in GitHub Desktop.
package com.cyant.chat.protocol;
import com.cyant.chat.CustomerEvents;
import com.cyant.chat.events.customer.InitiateEvent;
import com.cyant.chat.modal.CustomerUser;
import com.cyant.chat.modal.Organisation;
import com.cyant.chat.protocol.listener.CustomerActivity;
import com.cyant.chat.service.CustomerService;
import com.cyant.chat.service.OrganisationService;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.fge.jackson.JsonLoader;
import org.atmosphere.cache.UUIDBroadcasterCache;
import org.atmosphere.client.TrackMessageSizeInterceptor;
import org.atmosphere.config.service.AtmosphereHandlerService;
import org.atmosphere.config.service.Ready;
import org.atmosphere.cpr.*;
import org.atmosphere.interceptor.AtmosphereResourceLifecycleInterceptor;
import org.atmosphere.interceptor.SuspendTrackerInterceptor;
import org.atmosphere.util.ExcludeSessionBroadcaster;
import org.atmosphere.util.SimpleBroadcaster;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
@AtmosphereHandlerService(
path = "/customer",
interceptors = {
AtmosphereResourceLifecycleInterceptor.class,
TrackMessageSizeInterceptor.class,
SuspendTrackerInterceptor.class
},
broadcaster = SimpleBroadcaster.class,
broadcasterCache = UUIDBroadcasterCache.class
)
public class CustomerProtocol implements AtmosphereHandler
{
private final Logger logger = LoggerFactory.getLogger(CustomerProtocol.class);
private final ObjectMapper mapper = new ObjectMapper();
private static CustomerService customerService;
private static OrganisationService organisationService;
public static void setOrganisationService(OrganisationService service)
{
organisationService = service;
}
public static void setCustomerService(CustomerService service)
{
customerService = service;
}
@Ready
public void onReady(final AtmosphereResource resource)
{
// track users activity
resource.addEventListener(new CustomerActivity());
}
/**
* Initialize customer
*
* Must be the first method to be called when a customer connects, sets up the customer user and connects them
* to the given organisation. And notifies all the operators about them.
*
* @param resource the resource used to represent the connection
* @param data Contains the rest of the information about the user
*/
public void initialize(final AtmosphereResource resource, final JsonNode data)
{
logger.debug("CustomerProtocol::initialize {}", data);
try {
InitiateEvent event = mapper.readValue(data.traverse(), InitiateEvent.class);
Organisation organisation = organisationService.getById(event.getAppId());
if (organisation == null) {
throw new RuntimeException("Organisation was not found exception");
}
CustomerUser user = organisation.getCustomer(event.getUniqueId());
if (user == null) {
String broadcastIdentifier = String.format("/organisations/%d/customer/%s", event.getAppId(), event.getUniqueId());
ExcludeSessionBroadcaster broadcaster = BroadcasterFactory.getDefault().get(ExcludeSessionBroadcaster.class, broadcastIdentifier);
user = new CustomerUser(event.getUniqueId(), broadcaster);
String httpUserAgent = resource.getRequest().getHeader("User-Agent");
// populate customer information
customerService.populateCustomerInfo(user, httpUserAgent, "85.253.253.250");
organisation.addCustomer(user);
} else {
// todo: transmit the current user/conversation status
}
user.getBroadcaster().addAtmosphereResource(resource);
resource.session().setAttribute("user", user);
} catch (IOException e) {
e.printStackTrace();
}
}
public void changeWindowState(final AtmosphereResource resource, final JsonNode data)
{
try {
final CustomerUser user = (CustomerUser) resource.session().getAttribute("user");
final CustomerUser.WindowState state = CustomerUser.WindowState.valueOf(
data.get("state").asText().toUpperCase()
);
user.setWindowState(state);
} catch (IllegalArgumentException e) {
// todo: respond with illegal window state error
e.printStackTrace();
}
}
@Override
public void onRequest(AtmosphereResource resource) throws IOException
{
logger.debug("CustomerProtocol::onRequest {}", resource);
String message = resource.getRequest().getReader().readLine();
if (message == null) {
return;
}
JsonNode json = JsonLoader.fromString(message);
// parse the information
final String eventName = json.get("event").asText();
final JsonNode data = json.get("data");
final CustomerUser user = (CustomerUser) resource.session().getAttribute("user");
try {
final CustomerEvents event = CustomerEvents.valueOf(eventName.toUpperCase());
if (user == null && !event.equals(CustomerEvents.CONNECT)) {
throw new RuntimeException("Customer must connect before doing anything else.");
} else if (user != null) {
// broadcast to the rest of the browsers tabs
user.getBroadcaster().broadcast(message, resource);
}
switch (event)
{
case CONNECT:
initialize(resource, data);
break;
case WINDOW_EVENT:
changeWindowState(resource, data);
break;
}
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
}
@Override
public void onStateChange(AtmosphereResourceEvent event) throws IOException
{
logger.debug("CustomerProtocol::onRequest {}", event);
// just write out to the specific resource
event.getResource().write(event.getMessage().toString());
}
@Override
public void destroy()
{
logger.debug("CustomerProtocol::destroy");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment