Skip to content

Commit ffe862b

Browse files
authored
Added support for timeout when opening a TCPSocket. (#163)
* Enabled to set timeout value when opening TCPSocket. * Added connect_timeout description to README.
1 parent 29244bb commit ffe862b

File tree

3 files changed

+40
-1
lines changed

3 files changed

+40
-1
lines changed

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,15 @@ client.ca_file = path_to('root-ca.pem')
8989
client.connect()
9090
~~~
9191

92+
The default timeout when opening a TCP Socket is 30 seconds. To specify it explicitly, use 'connect_timeout =>':
93+
94+
~~~ ruby
95+
client = MQTT::Client.connect(
96+
:host => 'myserver.example.com',
97+
:connect_timeout => 15
98+
)
99+
~~~
100+
92101
The connection can either be made without the use of a block:
93102

94103
~~~ ruby

lib/mqtt/client.rb

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ class Client
3939
# Number of seconds to wait for acknowledgement packets (default is 5 seconds)
4040
attr_accessor :ack_timeout
4141

42+
# Number of seconds to connect to the server (default is 90 seconds)
43+
attr_accessor :connect_timeout
44+
4245
# Username to authenticate to the server with
4346
attr_accessor :username
4447

@@ -72,6 +75,7 @@ class Client
7275
:clean_session => true,
7376
:client_id => nil,
7477
:ack_timeout => 5,
78+
:connect_timeout => 30,
7579
:username => nil,
7680
:password => nil,
7781
:will_topic => nil,
@@ -239,7 +243,7 @@ def connect(clientid = nil)
239243

240244
unless connected?
241245
# Create network socket
242-
tcp_socket = TCPSocket.new(@host, @port)
246+
tcp_socket = open_tcp_socket
243247

244248
if @ssl
245249
# Set the protocol version
@@ -600,6 +604,19 @@ def next_packet_id
600604
@last_packet_id
601605
end
602606

607+
def open_tcp_socket
608+
return TCPSocket.new @host, @port, connect_timeout: @connect_timeout if RUBY_VERSION.to_f >= 3.0
609+
610+
begin
611+
Timeout.timeout(@connect_timeout) do
612+
return TCPSocket.new(@host, @port)
613+
end
614+
rescue Timeout::Error
615+
raise IO::TimeoutError, "Connection timed out for \"#{@host}\" port #{@port}" if defined? IO::TimeoutError
616+
raise Errno::ETIMEDOUT, "Connection timed out for \"#{@host}\" port #{@port}"
617+
end
618+
end
619+
603620
# ---- Deprecated attributes and methods ---- #
604621
public
605622

spec/mqtt_client_spec.rb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,19 @@ def wait_for_puback(id)
655655
client.instance_variable_set('@socket', socket)
656656
end
657657

658+
it "should respect connect_timeout" do
659+
client = MQTT::Client.new(:host => '198.51.100.1', :connect_timeout => 0.1)
660+
expect {
661+
client.connect
662+
}.to raise_error(
663+
if defined? IO::TimeoutError
664+
IO::TimeoutError
665+
else
666+
Errno::ETIMEDOUT
667+
end
668+
)
669+
end
670+
658671
it "should respect timeouts" do
659672
require "socket"
660673
rd, wr = UNIXSocket.pair

0 commit comments

Comments
 (0)