Created
July 12, 2013 10:31
-
-
Save macnibblet/5983426 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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