mqtt 0.4.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -13
- data/NEWS.md +15 -0
- data/README.md +1 -1
- data/lib/mqtt/client.rb +496 -469
- data/lib/mqtt/openssl_fix.rb +29 -0
- data/lib/mqtt/packet.rb +182 -235
- data/lib/mqtt/patches/string_encoding.rb +5 -7
- data/lib/mqtt/proxy.rb +85 -89
- data/lib/mqtt/sn/packet.rb +469 -512
- data/lib/mqtt/version.rb +1 -1
- data/lib/mqtt.rb +1 -3
- data/spec/mqtt_client_spec.rb +148 -16
- data/spec/mqtt_packet_spec.rb +8 -0
- data/spec/zz_client_integration_spec.rb +13 -2
- metadata +40 -27
@@ -11,12 +11,14 @@ class String
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def encode(encoding)
|
14
|
-
new =
|
14
|
+
new = dup
|
15
15
|
new.force_encoding(encoding)
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
19
|
class Encoding
|
20
|
+
attr_reader :name
|
21
|
+
|
20
22
|
def initialize(name)
|
21
23
|
@name = name
|
22
24
|
end
|
@@ -24,11 +26,7 @@ class Encoding
|
|
24
26
|
def to_s
|
25
27
|
@name
|
26
28
|
end
|
27
|
-
|
28
|
-
def name
|
29
|
-
@name
|
30
|
-
end
|
31
29
|
|
32
|
-
UTF_8 = Encoding.new(
|
33
|
-
ASCII_8BIT = Encoding.new(
|
30
|
+
UTF_8 = Encoding.new('UTF-8')
|
31
|
+
ASCII_8BIT = Encoding.new('ASCII-8BIT')
|
34
32
|
end
|
data/lib/mqtt/proxy.rb
CHANGED
@@ -1,119 +1,115 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
# Port to bind listening socket to
|
7
|
-
attr_reader :local_port
|
8
|
-
|
9
|
-
# Address of upstream server to send packets upstream to
|
10
|
-
attr_reader :server_host
|
11
|
-
|
12
|
-
# Port of upstream server to send packets upstream to.
|
13
|
-
attr_reader :server_port
|
14
|
-
|
15
|
-
# Time in seconds before disconnecting an idle connection
|
16
|
-
attr_reader :select_timeout
|
17
|
-
|
18
|
-
# Ruby Logger object to send informational messages to
|
19
|
-
attr_reader :logger
|
20
|
-
|
21
|
-
# Create a new MQTT Proxy instance.
|
22
|
-
#
|
23
|
-
# Possible argument keys:
|
24
|
-
#
|
25
|
-
# :local_host Address to bind listening socket to.
|
26
|
-
# :local_port Port to bind listening socket to.
|
27
|
-
# :server_host Address of upstream server to send packets upstream to.
|
28
|
-
# :server_port Port of upstream server to send packets upstream to.
|
29
|
-
# :select_timeout Time in seconds before disconnecting a connection.
|
30
|
-
# :logger Ruby Logger object to send informational messages to.
|
31
|
-
#
|
32
|
-
# NOTE: be careful not to connect to yourself!
|
33
|
-
def initialize(args={})
|
34
|
-
@local_host = args[:local_host] || '0.0.0.0'
|
35
|
-
@local_port = args[:local_port] || MQTT::DEFAULT_PORT
|
36
|
-
@server_host = args[:server_host]
|
37
|
-
@server_port = args[:server_port] || 18830
|
38
|
-
@select_timeout = args[:select_timeout] || 60
|
39
|
-
|
40
|
-
# Setup a logger
|
41
|
-
@logger = args[:logger]
|
42
|
-
if @logger.nil?
|
43
|
-
@logger = Logger.new(STDOUT)
|
44
|
-
@logger.level = Logger::INFO
|
45
|
-
end
|
1
|
+
module MQTT
|
2
|
+
# Class for implementing a proxy to filter/mangle MQTT packets.
|
3
|
+
class Proxy
|
4
|
+
# Address to bind listening socket to
|
5
|
+
attr_reader :local_host
|
46
6
|
|
47
|
-
#
|
48
|
-
|
49
|
-
@server_filter = nil
|
7
|
+
# Port to bind listening socket to
|
8
|
+
attr_reader :local_port
|
50
9
|
|
51
|
-
#
|
52
|
-
|
53
|
-
@logger.info "MQTT::Proxy listening on #{@local_host}:#{@local_port}"
|
54
|
-
end
|
10
|
+
# Address of upstream server to send packets upstream to
|
11
|
+
attr_reader :server_host
|
55
12
|
|
56
|
-
|
57
|
-
|
58
|
-
@client_filter = proc
|
59
|
-
end
|
13
|
+
# Port of upstream server to send packets upstream to.
|
14
|
+
attr_reader :server_port
|
60
15
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
16
|
+
# Time in seconds before disconnecting an idle connection
|
17
|
+
attr_reader :select_timeout
|
18
|
+
|
19
|
+
# Ruby Logger object to send informational messages to
|
20
|
+
attr_reader :logger
|
21
|
+
|
22
|
+
# A filter Proc for packets coming from the client (to the server).
|
23
|
+
attr_writer :client_filter
|
24
|
+
|
25
|
+
# A filter Proc for packets coming from the server (to the client).
|
26
|
+
attr_writer :server_filter
|
27
|
+
|
28
|
+
# Create a new MQTT Proxy instance.
|
29
|
+
#
|
30
|
+
# Possible argument keys:
|
31
|
+
#
|
32
|
+
# :local_host Address to bind listening socket to.
|
33
|
+
# :local_port Port to bind listening socket to.
|
34
|
+
# :server_host Address of upstream server to send packets upstream to.
|
35
|
+
# :server_port Port of upstream server to send packets upstream to.
|
36
|
+
# :select_timeout Time in seconds before disconnecting a connection.
|
37
|
+
# :logger Ruby Logger object to send informational messages to.
|
38
|
+
#
|
39
|
+
# NOTE: be careful not to connect to yourself!
|
40
|
+
def initialize(args = {})
|
41
|
+
@local_host = args[:local_host] || '0.0.0.0'
|
42
|
+
@local_port = args[:local_port] || MQTT::DEFAULT_PORT
|
43
|
+
@server_host = args[:server_host]
|
44
|
+
@server_port = args[:server_port] || 18_830
|
45
|
+
@select_timeout = args[:select_timeout] || 60
|
46
|
+
|
47
|
+
# Setup a logger
|
48
|
+
@logger = args[:logger]
|
49
|
+
if @logger.nil?
|
50
|
+
@logger = Logger.new(STDOUT)
|
51
|
+
@logger.level = Logger::INFO
|
52
|
+
end
|
53
|
+
|
54
|
+
# Default is not to have any filters
|
55
|
+
@client_filter = nil
|
56
|
+
@server_filter = nil
|
65
57
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
logger.
|
58
|
+
# Create TCP server socket
|
59
|
+
@server = TCPServer.open(@local_host, @local_port)
|
60
|
+
@logger.info "MQTT::Proxy listening on #{@local_host}:#{@local_port}"
|
61
|
+
end
|
62
|
+
|
63
|
+
# Start accepting connections and processing packets.
|
64
|
+
def run
|
65
|
+
loop do
|
66
|
+
# Wait for a client to connect and then create a thread for it
|
67
|
+
Thread.new(@server.accept) do |client_socket|
|
68
|
+
logger.info "Accepted client: #{client_socket.peeraddr.join(':')}"
|
69
|
+
server_socket = TCPSocket.new(@server_host, @server_port)
|
70
|
+
begin
|
71
|
+
process_packets(client_socket, server_socket)
|
72
|
+
rescue Exception => exp
|
73
|
+
logger.error exp.to_s
|
74
|
+
end
|
75
|
+
logger.info "Disconnected: #{client_socket.peeraddr.join(':')}"
|
76
|
+
server_socket.close
|
77
|
+
client_socket.close
|
77
78
|
end
|
78
|
-
logger.info "Disconnected: #{client_socket.peeraddr.join(':')}"
|
79
|
-
server_socket.close
|
80
|
-
client_socket.close
|
81
79
|
end
|
82
80
|
end
|
83
|
-
end
|
84
81
|
|
85
|
-
|
82
|
+
private
|
83
|
+
|
84
|
+
def process_packets(client_socket, server_socket)
|
85
|
+
loop do
|
86
|
+
# Wait for some data on either socket
|
87
|
+
selected = IO.select([client_socket, server_socket], nil, nil, @select_timeout)
|
86
88
|
|
87
|
-
def process_packets(client_socket,server_socket)
|
88
|
-
loop do
|
89
|
-
# Wait for some data on either socket
|
90
|
-
selected = IO.select([client_socket,server_socket], nil, nil, @select_timeout)
|
91
|
-
if selected.nil?
|
92
89
|
# Timeout
|
93
|
-
raise
|
94
|
-
|
90
|
+
raise 'Timeout in select' if selected.nil?
|
91
|
+
|
95
92
|
# Iterate through each of the sockets with data to read
|
96
93
|
if selected[0].include?(client_socket)
|
97
94
|
packet = MQTT::Packet.read(client_socket)
|
98
|
-
logger.debug "client -> <#{packet.
|
95
|
+
logger.debug "client -> <#{packet.type_name}>"
|
99
96
|
packet = @client_filter.call(packet) unless @client_filter.nil?
|
100
97
|
unless packet.nil?
|
101
98
|
server_socket.write(packet)
|
102
|
-
logger.debug "<#{packet.
|
99
|
+
logger.debug "<#{packet.type_name}> -> server"
|
103
100
|
end
|
104
101
|
elsif selected[0].include?(server_socket)
|
105
102
|
packet = MQTT::Packet.read(server_socket)
|
106
|
-
logger.debug "server -> <#{packet.
|
103
|
+
logger.debug "server -> <#{packet.type_name}>"
|
107
104
|
packet = @server_filter.call(packet) unless @server_filter.nil?
|
108
105
|
unless packet.nil?
|
109
106
|
client_socket.write(packet)
|
110
|
-
logger.debug "<#{packet.
|
107
|
+
logger.debug "<#{packet.type_name}> -> client"
|
111
108
|
end
|
112
109
|
else
|
113
|
-
logger.error
|
110
|
+
logger.error 'Problem with select: socket is neither server or client'
|
114
111
|
end
|
115
112
|
end
|
116
113
|
end
|
117
114
|
end
|
118
|
-
|
119
115
|
end
|