Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

It is now possible to specify a timeout when opening a TCPSocket. #163

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,15 @@ client.ca_file = path_to('root-ca.pem')
client.connect()
~~~

The default timeout when opening a TCP Socket is 30 seconds. To specify it explicitly, use 'connect_timeout =>':

~~~ ruby
client = MQTT::Client.connect(
:host => 'myserver.example.com',
:connect_timeout => 15
)
~~~

The connection can either be made without the use of a block:

~~~ ruby
Expand Down
19 changes: 18 additions & 1 deletion lib/mqtt/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ class Client
# Number of seconds to wait for acknowledgement packets (default is 5 seconds)
attr_accessor :ack_timeout

# Number of seconds to connect to the server (default is 90 seconds)
attr_accessor :connect_timeout

# Username to authenticate to the server with
attr_accessor :username

Expand Down Expand Up @@ -72,6 +75,7 @@ class Client
:clean_session => true,
:client_id => nil,
:ack_timeout => 5,
:connect_timeout => 30,
:username => nil,
:password => nil,
:will_topic => nil,
Expand Down Expand Up @@ -239,7 +243,7 @@ def connect(clientid = nil)

unless connected?
# Create network socket
tcp_socket = TCPSocket.new(@host, @port)
tcp_socket = open_tcp_socket

if @ssl
# Set the protocol version
Expand Down Expand Up @@ -600,6 +604,19 @@ def next_packet_id
@last_packet_id
end

def open_tcp_socket
return TCPSocket.new @host, @port, connect_timeout: @connect_timeout if RUBY_VERSION.to_f >= 3.0

begin
Timeout.timeout(@connect_timeout) do
return TCPSocket.new(@host, @port)
end
rescue Timeout::Error
raise IO::TimeoutError, "Connection timed out for \"#{@host}\" port #{@port}" if defined? IO::TimeoutError
raise Errno::ETIMEDOUT, "Connection timed out for \"#{@host}\" port #{@port}"
end
end

# ---- Deprecated attributes and methods ---- #
public

Expand Down
13 changes: 13 additions & 0 deletions spec/mqtt_client_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,19 @@ def wait_for_puback(id)
client.instance_variable_set('@socket', socket)
end

it "should respect connect_timeout" do
client = MQTT::Client.new(:host => '198.51.100.1', :connect_timeout => 0.1)
expect {
client.connect
}.to raise_error(
if defined? IO::TimeoutError
IO::TimeoutError
else
Errno::ETIMEDOUT
end
)
end

it "should respect timeouts" do
require "socket"
rd, wr = UNIXSocket.pair
Expand Down