diff --git a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java index 488189cfe..43800aca0 100644 --- a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java +++ b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java @@ -95,6 +95,7 @@ import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Writer; import java.lang.reflect.Constructor; +import java.net.InetSocketAddress; import java.net.Socket; import java.security.KeyManagementException; import java.security.KeyStore; @@ -498,7 +499,7 @@ public class XMPPTCPConnection extends AbstractXMPPConnection { } } - private void connectUsingConfiguration(ConnectionConfiguration config) throws SmackException, IOException { + private void connectUsingConfiguration(XMPPTCPConnectionConfiguration config) throws SmackException, IOException { try { populateHostAddresses(); } @@ -512,13 +513,14 @@ public class XMPPTCPConnection extends AbstractXMPPConnection { HostAddress hostAddress = it.next(); String host = hostAddress.getFQDN(); int port = hostAddress.getPort(); + if (config.getSocketFactory() == null) { + socket = new Socket(); + } + else { + socket = config.getSocketFactory().createSocket(); + } try { - if (config.getSocketFactory() == null) { - this.socket = new Socket(host, port); - } - else { - this.socket = config.getSocketFactory().createSocket(host, port); - } + socket.connect(new InetSocketAddress(host, port), config.getConnectTimeout()); } catch (Exception e) { exception = e; } diff --git a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnectionConfiguration.java b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnectionConfiguration.java index 57a46d9ef..200811652 100644 --- a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnectionConfiguration.java +++ b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnectionConfiguration.java @@ -20,11 +20,23 @@ import org.jivesoftware.smack.ConnectionConfiguration; public class XMPPTCPConnectionConfiguration extends ConnectionConfiguration { + /** + * The default connect timeout in milliseconds. Preinitialized with 30000 (30 seconds). If this value is changed, + * new Builder instances will use the new value as default. + */ + public static int DEFAULT_CONNECT_TIMEOUT = 30000; + private final boolean compressionEnabled; + /** + * How long the socket will wait until a TCP connection is established (in milliseconds). + */ + private final int connectTimeout; + private XMPPTCPConnectionConfiguration(Builder builder) { super(builder); compressionEnabled = builder.compressionEnabled; + connectTimeout = builder.connectTimeout; } /** @@ -40,12 +52,22 @@ public class XMPPTCPConnectionConfiguration extends ConnectionConfiguration { return compressionEnabled; } + /** + * How long the socket will wait until a TCP connection is established (in milliseconds). Defaults to {@link #DEFAULT_CONNECT_TIMEOUT}. + * + * @return the timeout value in milliseconds. + */ + public int getConnectTimeout() { + return connectTimeout; + } + public static Builder builder() { return new Builder(); } public static class Builder extends ConnectionConfiguration.Builder { private boolean compressionEnabled = false; + private int connectTimeout = DEFAULT_CONNECT_TIMEOUT; private Builder() { } @@ -57,12 +79,24 @@ public class XMPPTCPConnectionConfiguration extends ConnectionConfiguration { * up to 90%. By default compression is disabled. * * @param compressionEnabled if the connection is going to use stream compression. + * @return a reference to this object. */ public Builder setCompressionEnabled(boolean compressionEnabled) { this.compressionEnabled = compressionEnabled; return this; } + /** + * Set how long the socket will wait until a TCP connection is established (in milliseconds). + * + * @param connectTimeout the timeout value to be used in milliseconds. + * @return a reference to this object. + */ + public Builder setConnectTimeout(int connectTimeout) { + this.connectTimeout = connectTimeout; + return this; + } + @Override protected Builder getThis() { return this;