@@ -74,6 +74,8 @@ public abstract class WebSocketClient extends WebSocketAdapter implements Runnab
7474
7575 private CountDownLatch closeLatch = new CountDownLatch ( 1 );
7676
77+ private int timeout = 0 ;
78+
7779 WebSocketClientFactory wf = new WebSocketClientFactory () {
7880 @ Override
7981 public WebSocket createWebSocket ( WebSocketAdapter a , Draft d , Socket s ) {
@@ -101,10 +103,10 @@ public WebSocketClient( URI serverURI ) {
101103 * must call <var>connect</var> first to initiate the socket connection.
102104 */
103105 public WebSocketClient ( URI serverUri , Draft draft ) {
104- this ( serverUri , draft , null );
106+ this ( serverUri , draft , null , 0 );
105107 }
106108
107- public WebSocketClient ( URI serverUri , Draft draft , Map <String ,String > headers ) {
109+ public WebSocketClient ( URI serverUri , Draft draft , Map <String ,String > headers , int connecttimeout ) {
108110 if ( serverUri == null ) {
109111 throw new IllegalArgumentException ();
110112 }
@@ -114,6 +116,7 @@ public WebSocketClient( URI serverUri , Draft draft , Map<String,String> headers
114116 this .uri = serverUri ;
115117 this .draft = draft ;
116118 this .headers = headers ;
119+ this .timeout = connecttimeout ;
117120 }
118121
119122 /**
@@ -220,17 +223,23 @@ private final void interruptableRun() {
220223 return ;
221224 } catch ( /*IOException | SecurityException | UnresolvedAddressException*/ Exception e ) {//
222225 onWebsocketError ( conn , e );
223- conn .closeConnection ( CloseFrame .NEVERCONNECTED , e .getMessage () );
226+ // conn.closeConnection( CloseFrame.NEVERCONNECTED, e.getMessage() );
224227 return ;
225- }
228+ }
226229 conn = (WebSocketImpl ) wf .createWebSocket ( this , draft , channel .socket () );
227230 ByteBuffer buff = ByteBuffer .allocate ( WebSocket .RCVBUF );
228231 try /*IO*/ {
229232 while ( channel .isOpen () ) {
230233 SelectionKey key = null ;
231- selector .select ();
234+ selector .select ( timeout );
232235 Set <SelectionKey > keys = selector .selectedKeys ();
233236 Iterator <SelectionKey > i = keys .iterator ();
237+ if ( conn .getReadyState () == READYSTATE .NOTYETCONNECTED && !i .hasNext () ) {
238+ // Hack for issue #140:
239+ // Android does simply return form select without closing the channel if address is not reachable(which seems to be a bug in the android nio proivder)
240+ // TODO provide a way to fix this problem which does not require this hack
241+ throw new IOException ( "Host is not reachable(Android Hack)" );
242+ }
234243 while ( i .hasNext () ) {
235244 key = i .next ();
236245 i .remove ();
@@ -294,13 +303,13 @@ private int getPort() {
294303 }
295304
296305 private void finishConnect ( SelectionKey key ) throws IOException , InvalidHandshakeException {
297- if ( channel .isConnectionPending () ) {
298- channel .finishConnect ();
299- }
306+ if ( !channel .finishConnect () )
307+ return ;
300308 // Now that we're connected, re-register for only 'READ' keys.
301309 conn .key = key .interestOps ( SelectionKey .OP_READ | SelectionKey .OP_WRITE );
302310
303311 conn .channel = wrappedchannel = wf .wrapChannel ( key , uri .getHost (), getPort () );
312+ timeout = 0 ; // since connect is over
304313 sendHandshake ();
305314 }
306315
@@ -414,7 +423,6 @@ public void onCloseInitiated( int code, String reason ) {
414423 public void onClosing ( int code , String reason , boolean remote ) {
415424 }
416425
417-
418426 public WebSocket getConnection () {
419427 return conn ;
420428 }
0 commit comments