com.google.sitebricks.channel.WebsocketRoutingServlet Maven / Gradle / Ivy
package com.google.sitebricks.channel;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import javax.inject.Inject;
import javax.inject.Provider;
import javax.inject.Singleton;
import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.api.UpgradeRequest;
import org.eclipse.jetty.websocket.api.UpgradeResponse;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
import org.eclipse.jetty.websocket.api.annotations.WebSocket;
import org.eclipse.jetty.websocket.servlet.WebSocketCreator;
import org.eclipse.jetty.websocket.servlet.WebSocketServlet;
import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory;
import com.google.sitebricks.client.transport.Json;
/**
* @author [email protected] (Dhanji R. Prasanna)
* @author Jason van Zyl
*/
@Singleton
class WebSocketRoutingServlet extends WebSocketServlet {
private static final long serialVersionUID = -7234499580734312102L;
private final ChannelSwitchboard switchboard;
private final Provider channelListener;
private final Json json;
@Inject
WebSocketRoutingServlet(ChannelSwitchboard switchboard, Provider channelListener, Json json) {
this.switchboard = switchboard;
this.channelListener = channelListener;
this.json = json;
}
@Override
public void configure(WebSocketServletFactory factory) {
factory.setCreator(new SitebricksWebSocketCreator());
}
public class SitebricksWebSocketCreator implements WebSocketCreator {
@Override
public Object createWebSocket(UpgradeRequest req, UpgradeResponse resp) {
String socketId = req.getParameterMap().get(Switchboard.SB_SOCKET_ID)[0];
return new ChannelSocket(socketId);
}
}
@WebSocket
public class ChannelSocket implements Switchboard.Channel {
private String socketId;
private Session session;
public ChannelSocket(String socketId) {
this.socketId = socketId;
}
@OnWebSocketConnect
public void onWebSocketConnect(Session session) {
this.session = session;
switchboard.connect(socketId, this);
channelListener.get().connected(this);
}
public void onWebSocketBinary(byte[] payload, int offset, int len) {
}
@OnWebSocketMessage
public void onWebSocketText(String message) {
switchboard.receive(message);
}
@OnWebSocketError
public void onWebSocketError(Throwable cause) {
}
@OnWebSocketClose
public void onWebSocketClose(int statusCode, String reason) {
try {
channelListener.get().disconnected(this);
} finally {
switchboard.disconnect(socketId);
}
}
//
// Switchboard.Channel
//
@Override
public void send(E reply) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
json.out(out, null, reply);
byte[] bytes = out.toByteArray();
session.getRemote().sendString(new String(bytes));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
public String getName() {
return socketId;
}
}
}