Skip to content

Commit 8009a69

Browse files
committed
fix/hack regarding TooTallNate#140. WebSocketClient constructor now allows to specify a connect timeout.
1 parent 4b7f2bd commit 8009a69

File tree

1 file changed

+17
-9
lines changed

1 file changed

+17
-9
lines changed

src/main/java/org/java_websocket/client/WebSocketClient.java

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)