|
import java.net.InetSocketAddress |
|
import java.net.URI |
|
import java.util.HashMap |
|
import java.util.concurrent.Executors |
|
import org.jboss.netty.bootstrap.ClientBootstrap |
|
import org.jboss.netty.buffer.ChannelBuffers |
|
import org.jboss.netty.channel.Channel |
|
import org.jboss.netty.channel.ChannelFuture |
|
import org.jboss.netty.channel.ChannelPipeline |
|
import org.jboss.netty.channel.ChannelPipelineFactory |
|
import org.jboss.netty.channel.Channels |
|
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory |
|
import org.jboss.netty.handler.codec.http.HttpRequestEncoder |
|
import org.jboss.netty.handler.codec.http.HttpResponseDecoder |
|
import org.jboss.netty.handler.codec.http.websocketx.CloseWebSocketFrame |
|
import org.jboss.netty.handler.codec.http.websocketx.PingWebSocketFrame |
|
import org.jboss.netty.handler.codec.http.websocketx.TextWebSocketFrame |
|
import org.jboss.netty.handler.codec.http.websocketx.WebSocketClientHandshaker |
|
import org.jboss.netty.handler.codec.http.websocketx.WebSocketClientHandshakerFactory |
|
import org.jboss.netty.handler.codec.http.websocketx.WebSocketVersion |
|
|
|
class WebSocketClient(uri : URI) { |
|
|
|
def run() = { |
|
val bootstrap = new ClientBootstrap( |
|
new NioClientSocketChannelFactory(Executors.newCachedThreadPool(), |
|
Executors.newCachedThreadPool())) |
|
var ch : Channel = null |
|
try { |
|
val protocol = uri.getScheme() |
|
if (!"ws".equals(protocol)) { |
|
throw new IllegalArgumentException("Unsupported protocol: " + protocol) |
|
} |
|
val customHeaders = new HashMap[String, String]() |
|
customHeaders.put("MyHeader", "MyValue") |
|
// Connect with V13 (RFC 6455 aka HyBi-17). You can change it to V08 or V00. |
|
// If you change it to V00, ping is not supported and remember to change |
|
// HttpResponseDecoder to WebSocketHttpResponseDecoder in the pipeline. |
|
val handshaker = |
|
new WebSocketClientHandshakerFactory().newHandshaker( |
|
uri, WebSocketVersion.V13, null, false, customHeaders) |
|
bootstrap.setPipelineFactory(new ChannelPipelineFactory() { |
|
def getPipeline() = { |
|
val pipeline = Channels.pipeline() |
|
pipeline.addLast("decoder", new HttpResponseDecoder()) |
|
pipeline.addLast("encoder", new HttpRequestEncoder()) |
|
pipeline.addLast("ws-handler", new WebSocketClientHandler(handshaker)) |
|
pipeline |
|
} |
|
}) |
|
// Connect |
|
println("WebSocket Client connecting") |
|
val future = |
|
bootstrap.connect(new InetSocketAddress(uri.getHost(), uri.getPort())) |
|
future.syncUninterruptibly() |
|
ch = future.getChannel() |
|
handshaker.handshake(ch).syncUninterruptibly() |
|
// Send 10 messages and wait for responses |
|
println("WebSocket Client sending message") |
|
for (i <- 0 to 1000) { |
|
//ch.write(new TextWebSocketFrame("Message #" + i)) |
|
} |
|
// Ping |
|
println("WebSocket Client sending ping") |
|
ch.write(new PingWebSocketFrame(ChannelBuffers.copiedBuffer(Array(1, 2, 3, 4, 5, 6).map(_.toByte)))) |
|
// Close |
|
println("WebSocket Client sending close") |
|
ch.write(new CloseWebSocketFrame()) |
|
// WebSocketClientHandler will close the connection when the server |
|
// responds to the CloseWebSocketFrame. |
|
ch.getCloseFuture().awaitUninterruptibly() |
|
} |
|
|
|
if (ch != null) { |
|
//ch.close() |
|
} |
|
bootstrap.releaseExternalResources() |
|
} |
|
} |
|
|
|
object WebSocketClient { |
|
def main(args : Array[String]) = { |
|
val uri = |
|
if (args.length > 0) new URI(args(0)) |
|
else new URI("ws://localhost:8080/websocket") |
|
new WebSocketClient(uri).run() |
|
} |
|
} |