@@ -125,6 +125,11 @@ public class Options {
125
125
*/
126
126
public static final long MINIMUM_SOCKET_WRITE_TIMEOUT_GT_CONNECTION_TIMEOUT = 100 ;
127
127
128
+ /**
129
+ * Constant used for calculating if a socket read timeout is large enough.
130
+ */
131
+ public static final long MINIMUM_SOCKET_READ_TIMEOUT_GT_CONNECTION_TIMEOUT = 100 ;
132
+
128
133
/**
129
134
* Default server ping interval. The client will send a ping to the server on this interval to insure liveness.
130
135
* The server may send pings to the client as well, these are handled automatically by the library,
@@ -271,6 +276,11 @@ public class Options {
271
276
* {@link Builder#connectionTimeout(Duration) connectionTimeout}.
272
277
*/
273
278
public static final String PROP_CONNECTION_TIMEOUT = PFX + "timeout" ;
279
+ /**
280
+ * Property used to configure a builder from a Properties object. {@value}, see
281
+ * {@link Builder#socketReadTimeoutMillis(int) socketReadTimeoutMillis}.
282
+ */
283
+ public static final String PROP_SOCKET_READ_TIMEOUT_MS = PFX + "socket.read.timeout.ms" ;
274
284
/**
275
285
* Property used to configure a builder from a Properties object. {@value}, see
276
286
* {@link Builder#socketWriteTimeout(long) socketWriteTimeout}.
@@ -591,6 +601,7 @@ public class Options {
591
601
private final Duration reconnectJitter ;
592
602
private final Duration reconnectJitterTls ;
593
603
private final Duration connectionTimeout ;
604
+ private final int socketReadTimeoutMillis ;
594
605
private final Duration socketWriteTimeout ;
595
606
private final int socketSoLinger ;
596
607
private final Duration pingInterval ;
@@ -704,6 +715,7 @@ public static class Builder {
704
715
private Duration reconnectJitter = DEFAULT_RECONNECT_JITTER ;
705
716
private Duration reconnectJitterTls = DEFAULT_RECONNECT_JITTER_TLS ;
706
717
private Duration connectionTimeout = DEFAULT_CONNECTION_TIMEOUT ;
718
+ private int socketReadTimeoutMillis = 0 ;
707
719
private Duration socketWriteTimeout = DEFAULT_SOCKET_WRITE_TIMEOUT ;
708
720
private int socketSoLinger = -1 ;
709
721
private Duration pingInterval = DEFAULT_PING_INTERVAL ;
@@ -840,6 +852,7 @@ public Builder properties(Properties props) {
840
852
durationProperty (props , PROP_RECONNECT_JITTER_TLS , DEFAULT_RECONNECT_JITTER_TLS , d -> this .reconnectJitterTls = d );
841
853
longProperty (props , PROP_RECONNECT_BUF_SIZE , DEFAULT_RECONNECT_BUF_SIZE , l -> this .reconnectBufferSize = l );
842
854
durationProperty (props , PROP_CONNECTION_TIMEOUT , DEFAULT_CONNECTION_TIMEOUT , d -> this .connectionTimeout = d );
855
+ intProperty (props , PROP_SOCKET_READ_TIMEOUT_MS , -1 , i -> this .socketReadTimeoutMillis = i );
843
856
durationProperty (props , PROP_SOCKET_WRITE_TIMEOUT , DEFAULT_SOCKET_WRITE_TIMEOUT , d -> this .socketWriteTimeout = d );
844
857
intProperty (props , PROP_SOCKET_SO_LINGER , -1 , i -> socketSoLinger = i );
845
858
@@ -1273,6 +1286,16 @@ public Builder connectionTimeout(long connectionTimeoutMillis) {
1273
1286
return this ;
1274
1287
}
1275
1288
1289
+ /**
1290
+ * Set the timeout to use around socket reads
1291
+ * @param socketReadTimeoutMillis the timeout milliseconds
1292
+ * @return the Builder for chaining
1293
+ */
1294
+ public Builder socketReadTimeoutMillis (int socketReadTimeoutMillis ) {
1295
+ this .socketReadTimeoutMillis = socketReadTimeoutMillis ;
1296
+ return this ;
1297
+ }
1298
+
1276
1299
/**
1277
1300
* Set the timeout to use around socket writes
1278
1301
* @param socketWriteTimeoutMillis the timeout milliseconds
@@ -1285,7 +1308,7 @@ public Builder socketWriteTimeout(long socketWriteTimeoutMillis) {
1285
1308
1286
1309
/**
1287
1310
* Set the timeout to use around socket writes
1288
- * @param socketWriteTimeout the timeout milliseconds
1311
+ * @param socketWriteTimeout the timeout duration
1289
1312
* @return the Builder for chaining
1290
1313
*/
1291
1314
public Builder socketWriteTimeout (Duration socketWriteTimeout ) {
@@ -1311,7 +1334,7 @@ public Builder socketSoLinger(int socketSoLinger) {
1311
1334
/**
1312
1335
* Set the interval between attempts to pings the server. These pings are automated,
1313
1336
* and capped by {@link #maxPingsOut(int) maxPingsOut()}. As of 2.4.4 the library
1314
- * may way up to 2 * time to send a ping. Incoming traffic from the server can postpone
1337
+ * may wait up to 2 * time to send a ping. Incoming traffic from the server can postpone
1315
1338
* the next ping to avoid pings taking up bandwidth during busy messaging.
1316
1339
* Keep in mind that a ping requires a round trip to the server. Setting this value to a small
1317
1340
* number can result in quick failures due to maxPingsOut being reached, these failures will
@@ -1323,7 +1346,7 @@ public Builder socketSoLinger(int socketSoLinger) {
1323
1346
* @return the Builder for chaining
1324
1347
*/
1325
1348
public Builder pingInterval (Duration time ) {
1326
- this .pingInterval = time ;
1349
+ this .pingInterval = time == null ? DEFAULT_PING_INTERVAL : time ;
1327
1350
return this ;
1328
1351
}
1329
1352
@@ -1772,6 +1795,15 @@ else if (useDefaultTls) {
1772
1795
new DefaultThreadFactory (threadPrefix ));
1773
1796
}
1774
1797
1798
+ if (socketReadTimeoutMillis > 0 ) {
1799
+ long srtMin = pingInterval .toMillis () + MINIMUM_SOCKET_WRITE_TIMEOUT_GT_CONNECTION_TIMEOUT ;
1800
+ if (socketReadTimeoutMillis < srtMin ) {
1801
+ throw new IllegalStateException ("Socket Read Timeout must be at least "
1802
+ + MINIMUM_SOCKET_READ_TIMEOUT_GT_CONNECTION_TIMEOUT
1803
+ + " milliseconds greater than the Ping Interval" );
1804
+ }
1805
+ }
1806
+
1775
1807
if (socketWriteTimeout == null || socketWriteTimeout .toMillis () < 1 ) {
1776
1808
socketWriteTimeout = null ;
1777
1809
}
@@ -1833,6 +1865,7 @@ public Builder(Options o) {
1833
1865
this .reconnectJitter = o .reconnectJitter ;
1834
1866
this .reconnectJitterTls = o .reconnectJitterTls ;
1835
1867
this .connectionTimeout = o .connectionTimeout ;
1868
+ this .socketReadTimeoutMillis = o .socketReadTimeoutMillis ;
1836
1869
this .socketWriteTimeout = o .socketWriteTimeout ;
1837
1870
this .socketSoLinger = o .socketSoLinger ;
1838
1871
this .pingInterval = o .pingInterval ;
@@ -1896,6 +1929,7 @@ private Options(Builder b) {
1896
1929
this .reconnectJitter = b .reconnectJitter ;
1897
1930
this .reconnectJitterTls = b .reconnectJitterTls ;
1898
1931
this .connectionTimeout = b .connectionTimeout ;
1932
+ this .socketReadTimeoutMillis = b .socketReadTimeoutMillis ;
1899
1933
this .socketWriteTimeout = b .socketWriteTimeout ;
1900
1934
this .socketSoLinger = b .socketSoLinger ;
1901
1935
this .pingInterval = b .pingInterval ;
@@ -2213,7 +2247,14 @@ public Duration getConnectionTimeout() {
2213
2247
}
2214
2248
2215
2249
/**
2216
- * @return the socketWriteTimeout, see {@link Builder#socketWriteTimeout(long) socketWriteTimeout()} in the builder doc
2250
+ * @return the socketReadTimeoutMillis, see {@link Builder#socketReadTimeoutMillis(int) socketReadTimeoutMillis} in the builder doc
2251
+ */
2252
+ public int getSocketReadTimeoutMillis () {
2253
+ return socketReadTimeoutMillis ;
2254
+ }
2255
+
2256
+ /**
2257
+ * @return the socketWriteTimeout, see {@link Builder#socketWriteTimeout(long) socketWriteTimeout} in the builder doc
2217
2258
*/
2218
2259
public Duration getSocketWriteTimeout () {
2219
2260
return socketWriteTimeout ;
0 commit comments