From 2f76dd13a4745db4bd5120662e43510ec7904483 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Tue, 30 Aug 2011 00:21:14 +0200 Subject: [PATCH] Added getter and setter to configure the bind address. Removed uneffective setSoTimeout() call, it is not used for non-blocking sockets. Reworked javadocs. --- .../jetty/websocket/WebSocketClient.java | 153 ++++++++++++------ 1 file changed, 102 insertions(+), 51 deletions(-) diff --git a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketClient.java b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketClient.java index 91f04f839b2..0f9b61cfdb4 100644 --- a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketClient.java +++ b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketClient.java @@ -3,12 +3,12 @@ package org.eclipse.jetty.websocket; import java.io.IOException; import java.net.InetSocketAddress; import java.net.ProtocolException; +import java.net.SocketAddress; import java.net.URI; import java.nio.channels.ByteChannel; import java.nio.channels.SocketChannel; import java.util.List; import java.util.Map; -import java.util.Random; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CountDownLatch; @@ -17,21 +17,25 @@ import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import org.eclipse.jetty.io.ByteArrayBuffer; import org.eclipse.jetty.util.log.Logger; /* ------------------------------------------------------------ */ -/** WebSocket Client - *

This WebSocket Client class can create multiple websocket connections to multiple destinations. - * It uses the same {@link WebSocket} endpoint API as the server. - * Simple usage is as follows:

+/**
+ * 

{@link WebSocketClient} allows to create multiple connections to multiple destinations + * that can speak the websocket protocol.

+ *

When creating websocket connections, {@link WebSocketClient} accepts a {@link WebSocket} + * object (to receive events from the server), and returns a {@link WebSocket.Connection} to + * send data to the server.

+ *

Example usage is as follows:

+ *
  *   WebSocketClientFactory factory = new WebSocketClientFactory();
  *   factory.start();
- *   WebSocketClient client = factory.newClient();
- *   client.start();
  *
- *   WebSocket.Connection connection =  client.open(new URI("ws://127.0.0.1:8080/"),new WebSocket.OnTextMessage()
+ *   WebSocketClient client = factory.newWebSocketClient();
+ *   // Configure the client
+ *
+ *   WebSocket.Connection connection = client.open(new URI("ws://127.0.0.1:8080/"), new WebSocket.OnTextMessage()
  *   {
  *     public void onOpen(Connection connection)
  *     {
@@ -47,7 +51,7 @@ import org.eclipse.jetty.util.log.Logger;
  *     {
  *       // handle incoming message
  *     }
- *   }).get(5,TimeUnit.SECONDS);
+ *   }).get(5, TimeUnit.SECONDS);
  *
  *   connection.sendMessage("Hello World");
  * 
@@ -63,14 +67,17 @@ public class WebSocketClient private String _protocol; private int _maxIdleTime=-1; private MaskGen _maskGen; - + private SocketAddress _bindAddress; /* ------------------------------------------------------------ */ - /** Create a WebSocket Client with private factory. - *

Creates a WebSocketClient from a private WebSocketClientFactory. - * This can be wasteful of resources if many clients are created. - * @deprecated Use {@link WebSocketClientFactory} + /** + *

Creates a WebSocketClient from a private WebSocketClientFactory.

+ *

This can be wasteful of resources if many clients are created.

+ * + * @deprecated Use {@link WebSocketClientFactory#newWebSocketClient()} + * @throws Exception if the private WebSocketClientFactory fails to start */ + @Deprecated public WebSocketClient() throws Exception { _factory=new WebSocketClientFactory(); @@ -79,27 +86,51 @@ public class WebSocketClient } /* ------------------------------------------------------------ */ - /** Create a WebSocket Client with shared factory. - * @param threadpool + /** + *

Creates a WebSocketClient with shared WebSocketClientFactory.

+ * + * @param factory the shared {@link WebSocketClientFactory} */ public WebSocketClient(WebSocketClientFactory factory) { _factory=factory; _maskGen=_factory.getMaskGen(); } - + /* ------------------------------------------------------------ */ /** - * @return The factory this client was created with. + * @return The WebSocketClientFactory this client was created with. */ public WebSocketClientFactory getFactory() { return _factory; } - + /* ------------------------------------------------------------ */ - /** Get the maxIdleTime for connections opened by this client. - * @return The maxIdleTime in ms, or -1 if the default from {@link #getSelectorManager()} is used. + /** + * @return the address to bind the socket channel to + * @see #setBindAddress(SocketAddress) + */ + public SocketAddress getBindAddress() + { + return _bindAddress; + } + + /* ------------------------------------------------------------ */ + /** + * @param bindAddress the address to bind the socket channel to + * @see #getBindAddress() + */ + public void setBindAddress(SocketAddress bindAddress) + { + this._bindAddress = bindAddress; + } + + /* ------------------------------------------------------------ */ + /** + * @return The maxIdleTime in ms for connections opened by this client, + * or -1 if the default from {@link WebSocketClientFactory#getSelectorManager()} is used. + * @see #setMaxIdleTime(int) */ public int getMaxIdleTime() { @@ -107,8 +138,9 @@ public class WebSocketClient } /* ------------------------------------------------------------ */ - /** Set the maxIdleTime for connections opened by this client. - * @param maxIdleTime max idle time in ms + /** + * @param maxIdleTime The max idle time in ms for connections opened by this client + * @see #getMaxIdleTime() */ public void setMaxIdleTime(int maxIdleTime) { @@ -116,8 +148,9 @@ public class WebSocketClient } /* ------------------------------------------------------------ */ - /** Get the subprotocol string for connections opened by this client. - * @return The subprotocol + /** + * @return The subprotocol string for connections opened by this client. + * @see #setProtocol(String) */ public String getProtocol() { @@ -125,8 +158,9 @@ public class WebSocketClient } /* ------------------------------------------------------------ */ - /** Set the subprotocol string for connections opened by this client. - * @param protocol The subprotocol + /** + * @param protocol The subprotocol string for connections opened by this client. + * @see #getProtocol() */ public void setProtocol(String protocol) { @@ -134,8 +168,9 @@ public class WebSocketClient } /* ------------------------------------------------------------ */ - /** Get the origin of the client - * @return The clients Origin + /** + * @return The origin URI of the client + * @see #setOrigin(String) */ public String getOrigin() { @@ -143,8 +178,9 @@ public class WebSocketClient } /* ------------------------------------------------------------ */ - /** Set the origin of the client - * @param origin the origin of the client (eg "http://example.com") + /** + * @param origin The origin URI of the client (eg "http://example.com") + * @see #getOrigin() */ public void setOrigin(String origin) { @@ -152,40 +188,58 @@ public class WebSocketClient } /* ------------------------------------------------------------ */ + /** + *

Returns the map of the cookies that are sent during the initial HTTP handshake + * that upgrades to the websocket protocol.

+ * @return The read-write cookie map + */ public Map getCookies() { return _cookies; } /* ------------------------------------------------------------ */ + /** + * @return The list of websocket protocol extensions + */ public List getExtensions() { return _extensions; } /* ------------------------------------------------------------ */ + /** + * @return the mask generator to use, or null if not mask generator should be used + * @see #setMaskGen(MaskGen) + */ public MaskGen getMaskGen() { return _maskGen; } /* ------------------------------------------------------------ */ + /** + * @param maskGen the mask generator to use, or null if not mask generator should be used + * @see #getMaskGen() + */ public void setMaskGen(MaskGen maskGen) { _maskGen = maskGen; } /* ------------------------------------------------------------ */ - /** Open a WebSocket connection. - * Open a websocket connection to the URI and block until the connection is accepted or there is an error. + /** + *

Opens a websocket connection to the URI and blocks until the connection is accepted or there is an error.

+ * * @param uri The URI to connect to. * @param websocket The {@link WebSocket} instance to handle incoming events. * @param maxConnectTime The interval to wait for a successful connection * @param units the units of the maxConnectTime * @return A {@link WebSocket.Connection} - * @throws IOException - * @throws InterruptedException - * @throws TimeoutException + * @throws IOException if the connection fails + * @throws InterruptedException if the thread is interrupted + * @throws TimeoutException if the timeout elapses before the connection is completed + * @see #open(URI, WebSocket) */ public WebSocket.Connection open(URI uri, WebSocket websocket,long maxConnectTime,TimeUnit units) throws IOException, InterruptedException, TimeoutException { @@ -207,14 +261,15 @@ public class WebSocketClient } /* ------------------------------------------------------------ */ - /** Asynchronously open a websocket connection. - * Open a websocket connection and return a {@link Future} to obtain the connection. - * The caller must call {@link Future#get(long, TimeUnit)} if they wish to impose a connect timeout on the open. + /** + *

Asynchronously opens a websocket connection and returns a {@link Future} to obtain the connection.

+ *

The caller must call {@link Future#get(long, TimeUnit)} if they wish to impose a connect timeout on the open.

* * @param uri The URI to connect to. * @param websocket The {@link WebSocket} instance to handle incoming events. * @return A {@link Future} to the {@link WebSocket.Connection} - * @throws IOException + * @throws IOException if the connection fails + * @see #open(URI, WebSocket, long, TimeUnit) */ public Future open(URI uri, WebSocket websocket) throws IOException { @@ -227,12 +282,10 @@ public class WebSocketClient throw new IOException("wss not supported"); SocketChannel channel = SocketChannel.open(); + if (_bindAddress != null) + channel.socket().bind(_bindAddress); channel.socket().setTcpNoDelay(true); int maxIdleTime = getMaxIdleTime(); - if (maxIdleTime<0) - maxIdleTime=(int)_factory.getSelectorManager().getMaxIdleTime(); - if (maxIdleTime>0) - channel.socket().setSoTimeout(maxIdleTime); InetSocketAddress address=new InetSocketAddress(uri.getHost(),uri.getPort()); @@ -245,13 +298,12 @@ public class WebSocketClient return holder; } - /* ------------------------------------------------------------ */ /** The Future Websocket Connection. */ - static class WebSocketFuture implements Future + private static class WebSocketFuture implements Future { - final WebSocket _websocket;; + final WebSocket _websocket; final URI _uri; final String _protocol; final String _origin; @@ -366,7 +418,7 @@ public class WebSocketClient { return _maskGen; } - + public String toString() { return "[" + _uri + ","+_websocket+"]@"+hashCode(); @@ -433,7 +485,7 @@ public class WebSocketClient _done.await(timeout,unit); ByteChannel channel=null; org.eclipse.jetty.websocket.WebSocket.Connection connection=null; - Throwable exception=null; + Throwable exception; synchronized (this) { exception=_exception; @@ -476,6 +528,5 @@ public class WebSocketClient __log.debug(e); } } - } }