package org.chililog.client.websocket; import java.net.InetSocketAddress; import java.net.URI; import org.chililog.server.pubsub.websocket.WebSocketClientHandshaker; import org.chililog.server.pubsub.websocket.WebSocketClientHandshakerFactory; import org.chililog.server.pubsub.websocket.WebSocketFrame; import org.chililog.server.pubsub.websocket.WebSocketSpecificationVersion; import org.jboss.netty.bootstrap.ClientBootstrap; import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelFuture; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.ChannelStateEvent; import org.jboss.netty.channel.ExceptionEvent; import org.jboss.netty.channel.MessageEvent; import org.jboss.netty.channel.SimpleChannelUpstreamHandler; import org.jboss.netty.handler.codec.http.HttpResponse; import org.jboss.netty.util.CharsetUtil; /** * Copied from https://github.com/cgbystrom/netty-tools * * Handles socket communication for a connected WebSocket client Not intended for end-users. Please use * {@link WebSocketClient} or {@link WebSocketCallback} for controlling your client. * * @author <a href="http://www.pedantique.org/">Carl Byström</a> */ public class WebSocketClientHandler extends SimpleChannelUpstreamHandler implements WebSocketClient { private ClientBootstrap bootstrap; private URI url; private WebSocketCallback callback; private Channel channel; private WebSocketClientHandshaker handshaker = null; private WebSocketSpecificationVersion version; public WebSocketClientHandler(ClientBootstrap bootstrap, URI url, WebSocketSpecificationVersion version, WebSocketCallback callback) { this.bootstrap = bootstrap; this.url = url; this.version = version; this.callback = callback; } @Override public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { channel = e.getChannel(); this.handshaker = new WebSocketClientHandshakerFactory().newHandshaker(url, version, null, false); handshaker.beginOpeningHandshake(ctx, channel); } @Override public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { callback.onDisconnect(this); } @Override public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { if (!handshaker.isOpeningHandshakeCompleted()) { handshaker.endOpeningHandshake(ctx, (HttpResponse) e.getMessage()); callback.onConnect(this); return; } if (e.getMessage() instanceof HttpResponse) { HttpResponse response = (HttpResponse) e.getMessage(); throw new WebSocketException("Unexpected HttpResponse (status=" + response.getStatus() + ", content=" + response.getContent().toString(CharsetUtil.UTF_8) + ")"); } WebSocketFrame frame = (WebSocketFrame) e.getMessage(); callback.onMessage(this, frame); } @Override public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception { final Throwable t = e.getCause(); callback.onError(t); e.getChannel().close(); } public ChannelFuture connect() { return bootstrap.connect(new InetSocketAddress(url.getHost(), url.getPort())); } public ChannelFuture disconnect() { return channel.close(); } public ChannelFuture send(WebSocketFrame frame) { return channel.write(frame); } public URI getUrl() { return url; } public void setUrl(URI url) { this.url = url; } }