paho-mqtt 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/paho-mqtt.rb +72 -1
- data/lib/paho_mqtt/client.rb +182 -708
- data/lib/paho_mqtt/connection_helper.rb +167 -0
- data/lib/paho_mqtt/handler.rb +271 -0
- data/lib/paho_mqtt/packet.rb +14 -0
- data/lib/paho_mqtt/packet/base.rb +17 -0
- data/lib/paho_mqtt/packet/connack.rb +19 -3
- data/lib/paho_mqtt/packet/connect.rb +50 -21
- data/lib/paho_mqtt/packet/disconnect.rb +18 -1
- data/lib/paho_mqtt/packet/pingreq.rb +17 -0
- data/lib/paho_mqtt/packet/pingresp.rb +17 -0
- data/lib/paho_mqtt/packet/puback.rb +17 -1
- data/lib/paho_mqtt/packet/pubcomp.rb +17 -0
- data/lib/paho_mqtt/packet/publish.rb +17 -0
- data/lib/paho_mqtt/packet/pubrec.rb +17 -0
- data/lib/paho_mqtt/packet/pubrel.rb +17 -0
- data/lib/paho_mqtt/packet/suback.rb +17 -0
- data/lib/paho_mqtt/packet/subscribe.rb +17 -0
- data/lib/paho_mqtt/packet/unsuback.rb +17 -0
- data/lib/paho_mqtt/packet/unsubscribe.rb +17 -0
- data/lib/paho_mqtt/publisher.rb +180 -0
- data/lib/paho_mqtt/sender.rb +90 -0
- data/lib/paho_mqtt/ssl_helper.rb +42 -0
- data/lib/paho_mqtt/subscriber.rb +195 -0
- data/lib/paho_mqtt/version.rb +1 -1
- metadata +8 -3
- data/LICENSE.txt +0 -21
@@ -0,0 +1,180 @@
|
|
1
|
+
# Copyright (c) 2016-2017 Pierre Goudet <p-goudet@ruby-dev.jp>
|
2
|
+
#
|
3
|
+
# All rights reserved. This program and the accompanying materials
|
4
|
+
# are made available under the terms of the Eclipse Public License v1.0
|
5
|
+
# and Eclipse Distribution License v1.0 which accompany this distribution.
|
6
|
+
#
|
7
|
+
# The Eclipse Public License is available at
|
8
|
+
# https://eclipse.org/org/documents/epl-v10.php.
|
9
|
+
# and the Eclipse Distribution License is available at
|
10
|
+
# https://eclipse.org/org/documents/edl-v10.php.
|
11
|
+
#
|
12
|
+
# Contributors:
|
13
|
+
# Pierre Goudet - initial committer
|
14
|
+
|
15
|
+
module PahoMqtt
|
16
|
+
class Publisher
|
17
|
+
|
18
|
+
def initialize(sender)
|
19
|
+
@waiting_puback = []
|
20
|
+
@waiting_pubrec = []
|
21
|
+
@waiting_pubrel = []
|
22
|
+
@waiting_pubcomp = []
|
23
|
+
@puback_mutex = Mutex.new
|
24
|
+
@pubrec_mutex = Mutex.new
|
25
|
+
@pubrel_mutex = Mutex.new
|
26
|
+
@pubcomp_mutex = Mutex.new
|
27
|
+
@sender = sender
|
28
|
+
end
|
29
|
+
|
30
|
+
def sender=(sender)
|
31
|
+
@sender = sender
|
32
|
+
end
|
33
|
+
|
34
|
+
def send_publish(topic, payload, retain, qos, new_id)
|
35
|
+
packet = PahoMqtt::Packet::Publish.new(
|
36
|
+
:id => new_id,
|
37
|
+
:topic => topic,
|
38
|
+
:payload => payload,
|
39
|
+
:retain => retain,
|
40
|
+
:qos => qos
|
41
|
+
)
|
42
|
+
@sender.append_to_writing(packet)
|
43
|
+
case qos
|
44
|
+
when 1
|
45
|
+
@puback_mutex.synchronize{
|
46
|
+
@waiting_puback.push({:id => new_id, :packet => packet, :timestamp => Time.now})
|
47
|
+
}
|
48
|
+
when 2
|
49
|
+
@pubrec_mutex.synchronize{
|
50
|
+
@waiting_pubrec.push({:id => new_id, :packet => packet, :timestamp => Time.now})
|
51
|
+
}
|
52
|
+
end
|
53
|
+
MQTT_ERR_SUCCESS
|
54
|
+
end
|
55
|
+
|
56
|
+
def do_publish(qos, packet_id)
|
57
|
+
case qos
|
58
|
+
when 0
|
59
|
+
when 1
|
60
|
+
send_puback(packet_id)
|
61
|
+
when 2
|
62
|
+
send_pubrec(packet_id)
|
63
|
+
else
|
64
|
+
@logger.error("The packet qos value is invalid in publish.") if logger?
|
65
|
+
raise PacketException
|
66
|
+
end
|
67
|
+
MQTT_ERR_SUCCESS
|
68
|
+
end
|
69
|
+
|
70
|
+
def send_puback(packet_id)
|
71
|
+
packet = PahoMqtt::Packet::Puback.new(
|
72
|
+
:id => packet_id
|
73
|
+
)
|
74
|
+
@sender.append_to_writing(packet)
|
75
|
+
MQTT_ERR_SUCCESS
|
76
|
+
end
|
77
|
+
|
78
|
+
def do_puback(packet_id)
|
79
|
+
@puback_mutex.synchronize{
|
80
|
+
@waiting_puback.delete_if { |pck| pck[:id] == packet_id }
|
81
|
+
}
|
82
|
+
MQTT_ERR_SUCCESS
|
83
|
+
end
|
84
|
+
|
85
|
+
def send_pubrec(packet_id)
|
86
|
+
packet = PahoMqtt::Packet::Pubrec.new(
|
87
|
+
:id => packet_id
|
88
|
+
)
|
89
|
+
@sender.append_to_writing(packet)
|
90
|
+
@pubrel_mutex.synchronize{
|
91
|
+
@waiting_pubrel.push({:id => packet_id , :packet => packet, :timestamp => Time.now})
|
92
|
+
}
|
93
|
+
MQTT_ERR_SUCCESS
|
94
|
+
end
|
95
|
+
|
96
|
+
def do_pubrec(packet_id)
|
97
|
+
@pubrec_mutex.synchronize {
|
98
|
+
@waiting_pubrec.delete_if { |pck| pck[:id] == packet_id }
|
99
|
+
}
|
100
|
+
send_pubrel(packet_id)
|
101
|
+
MQTT_ERR_SUCCESS
|
102
|
+
end
|
103
|
+
|
104
|
+
def send_pubrel(packet_id)
|
105
|
+
packet = PahoMqtt::Packet::Pubrel.new(
|
106
|
+
:id => packet_id
|
107
|
+
)
|
108
|
+
@sender.append_to_writing(packet)
|
109
|
+
@pubcomp_mutex.synchronize{
|
110
|
+
@waiting_pubcomp.push({:id => packet_id, :packet => packet, :timestamp => Time.now})
|
111
|
+
}
|
112
|
+
MQTT_ERR_SUCCESS
|
113
|
+
end
|
114
|
+
|
115
|
+
def do_pubrel(packet_id)
|
116
|
+
@pubrel_mutex.synchronize {
|
117
|
+
@waiting_pubrel.delete_if { |pck| pck[:id] == packet_id }
|
118
|
+
}
|
119
|
+
send_pubcomp(packet_id)
|
120
|
+
MQTT_ERR_SUCCESS
|
121
|
+
end
|
122
|
+
|
123
|
+
def send_pubcomp(packet_id)
|
124
|
+
packet = PahoMqtt::Packet::Pubcomp.new(
|
125
|
+
:id => packet_id
|
126
|
+
)
|
127
|
+
@sender.append_to_writing(packet)
|
128
|
+
MQTT_ERR_SUCCESS
|
129
|
+
end
|
130
|
+
|
131
|
+
def do_pubcomp(packet_id)
|
132
|
+
@pubcomp_mutex.synchronize {
|
133
|
+
@waiting_pubcomp.delete_if { |pck| pck[:id] == packet_id }
|
134
|
+
}
|
135
|
+
MQTT_ERR_SUCCESS
|
136
|
+
end
|
137
|
+
|
138
|
+
def config_all_message_queue
|
139
|
+
config_message_queue(@waiting_puback, @puback_mutex, MAX_PUBACK)
|
140
|
+
config_message_queue(@waiting_pubrec, @pubrec_mutex, MAX_PUBREC)
|
141
|
+
config_message_queue(@waiting_pubrel, @pubrel_mutex, MAX_PUBREL)
|
142
|
+
config_message_queue(@waiting_pubcomp, @pubcomp_mutex, MAX_PUBCOMP)
|
143
|
+
end
|
144
|
+
|
145
|
+
def config_message_queue(queue, mutex, max_packet)
|
146
|
+
mutex.synchronize {
|
147
|
+
cnt = 0
|
148
|
+
queue.each do |pck|
|
149
|
+
pck[:packet].dup ||= true
|
150
|
+
if cnt <= max_packet
|
151
|
+
@sender.append_to_writing(pck[:packet])
|
152
|
+
cnt += 1
|
153
|
+
end
|
154
|
+
end
|
155
|
+
}
|
156
|
+
end
|
157
|
+
|
158
|
+
def check_waiting_publisher
|
159
|
+
@sender.check_ack_alive(@waiting_puback, @puback_mutex, MAX_PUBACK)
|
160
|
+
@sender.check_ack_alive(@waiting_pubrec, @pubrec_mutex, MAX_PUBREC)
|
161
|
+
@sender.check_ack_alive(@waiting_pubrel, @pubrel_mutex, MAX_PUBREL)
|
162
|
+
@sender.check_ack_alive(@waiting_pubcomp, @pubcomp_mutex, MAX_PUBCOMP)
|
163
|
+
end
|
164
|
+
|
165
|
+
def flush_publisher
|
166
|
+
@puback_mutex.synchronize {
|
167
|
+
@waiting_puback = []
|
168
|
+
}
|
169
|
+
@pubrec_mutex.synchronize {
|
170
|
+
@waiting_pubrec = []
|
171
|
+
}
|
172
|
+
@pubrel_mutex.synchronize {
|
173
|
+
@waiting_pubrel = []
|
174
|
+
}
|
175
|
+
@pubcomp_mutex.synchronize {
|
176
|
+
@waiting_pubcomp = []
|
177
|
+
}
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
# Copyright (c) 2016-2017 Pierre Goudet <p-goudet@ruby-dev.jp>
|
2
|
+
#
|
3
|
+
# All rights reserved. This program and the accompanying materials
|
4
|
+
# are made available under the terms of the Eclipse Public License v1.0
|
5
|
+
# and Eclipse Distribution License v1.0 which accompany this distribution.
|
6
|
+
#
|
7
|
+
# The Eclipse Public License is available at
|
8
|
+
# https://eclipse.org/org/documents/epl-v10.php.
|
9
|
+
# and the Eclipse Distribution License is available at
|
10
|
+
# https://eclipse.org/org/documents/edl-v10.php.
|
11
|
+
#
|
12
|
+
# Contributors:
|
13
|
+
# Pierre Goudet - initial committer
|
14
|
+
|
15
|
+
module PahoMqtt
|
16
|
+
class Sender
|
17
|
+
|
18
|
+
attr_accessor :last_ping_req
|
19
|
+
|
20
|
+
def initialize(ack_timeout)
|
21
|
+
@socket = nil
|
22
|
+
@writing_queue = []
|
23
|
+
@writing_mutex = Mutex.new
|
24
|
+
@last_ping_req = -1
|
25
|
+
@ack_timeout = ack_timeout
|
26
|
+
end
|
27
|
+
|
28
|
+
def socket=(socket)
|
29
|
+
@socket = socket
|
30
|
+
end
|
31
|
+
|
32
|
+
def send_packet(packet)
|
33
|
+
begin
|
34
|
+
@socket.write(packet.to_s) unless @socket.nil? || @socket.closed?
|
35
|
+
@last_ping_req = Time.now
|
36
|
+
MQTT_ERR_SUCCESS
|
37
|
+
rescue StandardError
|
38
|
+
raise WritingException
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def append_to_writing(packet)
|
43
|
+
@writing_mutex.synchronize {
|
44
|
+
@writing_queue.push(packet)
|
45
|
+
}
|
46
|
+
MQTT_ERR_SUCCESS
|
47
|
+
end
|
48
|
+
|
49
|
+
@writing_mutex.synchronize {
|
50
|
+
def writing_loop(max_packet)
|
51
|
+
cnt = 0
|
52
|
+
while !@writing_queue.empty? && cnt < max_packet do
|
53
|
+
packet = @writing_queue.shift
|
54
|
+
send_packet(packet)
|
55
|
+
cnt += 1
|
56
|
+
end
|
57
|
+
}
|
58
|
+
MQTT_ERR_SUCCESS
|
59
|
+
end
|
60
|
+
|
61
|
+
def flush_waiting_packet(sending=true)
|
62
|
+
if sending
|
63
|
+
@writing_mutex.synchronize {
|
64
|
+
@writing_queue.each do |m|
|
65
|
+
send_packet(m)
|
66
|
+
end
|
67
|
+
}
|
68
|
+
else
|
69
|
+
@writing_queue = []
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def check_ack_alive(queue, mutex, max_packet)
|
74
|
+
mutex.synchronize {
|
75
|
+
now = Time.now
|
76
|
+
cnt = 0
|
77
|
+
queue.each do |pck|
|
78
|
+
if now >= pck[:timestamp] + @ack_timeout
|
79
|
+
pck[:packet].dup ||= true unless pck[:packet].class == PahoMqtt::Packet::Subscribe || pck[:packet].class == PahoMqtt::Packet::Unsubscribe
|
80
|
+
unless cnt > max_packet
|
81
|
+
append_to_writing(pck[:packet])
|
82
|
+
pck[:timestamp] = now
|
83
|
+
cnt += 1
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
}
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# Copyright (c) 2016-2017 Pierre Goudet <p-goudet@ruby-dev.jp>
|
2
|
+
#
|
3
|
+
# All rights reserved. This program and the accompanying materials
|
4
|
+
# are made available under the terms of the Eclipse Public License v1.0
|
5
|
+
# and Eclipse Distribution License v1.0 which accompany this distribution.
|
6
|
+
#
|
7
|
+
# The Eclipse Public License is available at
|
8
|
+
# https://eclipse.org/org/documents/epl-v10.php.
|
9
|
+
# and the Eclipse Distribution License is available at
|
10
|
+
# https://eclipse.org/org/documents/edl-v10.php.
|
11
|
+
#
|
12
|
+
# Contributors:
|
13
|
+
# Pierre Goudet - initial committer
|
14
|
+
|
15
|
+
require 'openssl'
|
16
|
+
|
17
|
+
module PahoMqtt
|
18
|
+
module SSLHelper
|
19
|
+
extend self
|
20
|
+
|
21
|
+
def config_ssl_context(cert_path, key_path, ca_path=nil)
|
22
|
+
ssl_context = OpenSSL::SSL::SSLContext.new
|
23
|
+
set_cert(cert_path, ssl_context)
|
24
|
+
set_key(key_path, ssl_context)
|
25
|
+
set_root_ca(ca_path, ssl_context)
|
26
|
+
ssl_context.verify_mode = OpenSSL::SSL::VERIFY_PEER unless ca_path.nil?
|
27
|
+
ssl_context
|
28
|
+
end
|
29
|
+
|
30
|
+
def set_cert(cert_path, ssl_context)
|
31
|
+
ssl_context.cert = OpenSSL::X509::Certificate.new(File.read(cert_path))
|
32
|
+
end
|
33
|
+
|
34
|
+
def set_key(key_path, ssl_context)
|
35
|
+
ssl_context.key = OpenSSL::PKey::RSA.new(File.read(key_path))
|
36
|
+
end
|
37
|
+
|
38
|
+
def set_root_ca(ca_path, ssl_context)
|
39
|
+
ssl_context.ca_file = ca_path
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,195 @@
|
|
1
|
+
# Copyright (c) 2016-2017 Pierre Goudet <p-goudet@ruby-dev.jp>
|
2
|
+
#
|
3
|
+
# All rights reserved. This program and the accompanying materials
|
4
|
+
# are made available under the terms of the Eclipse Public License v1.0
|
5
|
+
# and Eclipse Distribution License v1.0 which accompany this distribution.
|
6
|
+
#
|
7
|
+
# The Eclipse Public License is available at
|
8
|
+
# https://eclipse.org/org/documents/epl-v10.php.
|
9
|
+
# and the Eclipse Distribution License is available at
|
10
|
+
# https://eclipse.org/org/documents/edl-v10.php.
|
11
|
+
#
|
12
|
+
# Contributors:
|
13
|
+
# Pierre Goudet - initial committer
|
14
|
+
|
15
|
+
module PahoMqtt
|
16
|
+
class Subscriber
|
17
|
+
|
18
|
+
attr_reader :subscribed_topics
|
19
|
+
|
20
|
+
def initialize(sender)
|
21
|
+
@waiting_suback = []
|
22
|
+
@waiting_unsuback = []
|
23
|
+
@subscribed_mutex = Mutex.new
|
24
|
+
@subscribed_topics = []
|
25
|
+
@suback_mutex = Mutex.new
|
26
|
+
@unsuback_mutex = Mutex.new
|
27
|
+
@sender = sender
|
28
|
+
end
|
29
|
+
|
30
|
+
def sender=(sender)
|
31
|
+
@sender = sender
|
32
|
+
end
|
33
|
+
|
34
|
+
def config_subscription(new_id)
|
35
|
+
unless @subscribed_topics == [] || @subscribed_topics.nil?
|
36
|
+
packet = PahoMqtt::Packet::Subscribe.new(
|
37
|
+
:id => new_id,
|
38
|
+
:topics => @subscribed_topics
|
39
|
+
)
|
40
|
+
@subscribed_mutex.synchronize {
|
41
|
+
@subscribed_topics = []
|
42
|
+
}
|
43
|
+
@suback_mutex.synchronize {
|
44
|
+
@waiting_suback.push({ :id => new_id, :packet => packet, :timestamp => Time.now })
|
45
|
+
}
|
46
|
+
@sender.send_packet(packet)
|
47
|
+
end
|
48
|
+
MQTT_ERR_SUCCESS
|
49
|
+
end
|
50
|
+
|
51
|
+
def add_subscription(max_qos, packet_id, adjust_qos)
|
52
|
+
@suback_mutex.synchronize {
|
53
|
+
adjust_qos, @waiting_suback = @waiting_suback.partition { |pck| pck[:id] == packet_id }
|
54
|
+
}
|
55
|
+
if adjust_qos.length == 1
|
56
|
+
adjust_qos = adjust_qos.first[:packet].topics
|
57
|
+
adjust_qos.each do |t|
|
58
|
+
if [0, 1, 2].include?(max_qos[0])
|
59
|
+
t[1] = max_qos.shift
|
60
|
+
elsif max_qos[0] == 128
|
61
|
+
adjust_qos.delete(t)
|
62
|
+
else
|
63
|
+
|
64
|
+
@logger.error("The qos value is invalid in subscribe.") if logger?
|
65
|
+
raise PacketException
|
66
|
+
end
|
67
|
+
end
|
68
|
+
else
|
69
|
+
@logger.error("The packet id is invalid, already used.") if logger?
|
70
|
+
raise PacketException
|
71
|
+
end
|
72
|
+
@subscribed_mutex.synchronize {
|
73
|
+
@subscribed_topics.concat(adjust_qos)
|
74
|
+
}
|
75
|
+
MQTT_ERR_SUCCESS
|
76
|
+
end
|
77
|
+
|
78
|
+
def remove_subscription(packet_id, to_unsub)
|
79
|
+
@unsuback_mutex.synchronize {
|
80
|
+
to_unsub, @waiting_unsuback = @waiting_unsuback.partition { |pck| pck[:id] == packet_id }
|
81
|
+
}
|
82
|
+
|
83
|
+
if to_unsub.length == 1
|
84
|
+
to_unsub = to_unsub.first[:packet].topics
|
85
|
+
else
|
86
|
+
@logger.error("The packet id is invalid, already used.") if logger?
|
87
|
+
raise PacketException
|
88
|
+
end
|
89
|
+
|
90
|
+
@subscribed_mutex.synchronize {
|
91
|
+
to_unsub.each do |filter|
|
92
|
+
@subscribed_topics.delete_if { |topic| match_filter(topic.first, filter.first) }
|
93
|
+
end
|
94
|
+
}
|
95
|
+
MQTT_ERR_SUCCESS
|
96
|
+
end
|
97
|
+
|
98
|
+
def send_subscribe(topics, new_id)
|
99
|
+
unless valid_topics?(topics) == MQTT_ERR_FAIL
|
100
|
+
packet = PahoMqtt::Packet::Subscribe.new(
|
101
|
+
:id => new_id,
|
102
|
+
:topics => topics
|
103
|
+
)
|
104
|
+
@sender.append_to_writing(packet)
|
105
|
+
@suback_mutex.synchronize {
|
106
|
+
@waiting_suback.push({ :id => new_id, :packet => packet, :timestamp => Time.now })
|
107
|
+
}
|
108
|
+
MQTT_ERR_SUCCESS
|
109
|
+
else
|
110
|
+
raise ProtocolViolation
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def send_unsubscribe(topics, new_id)
|
115
|
+
unless valid_topics?(topics) == MQTT_ERR_FAIL
|
116
|
+
packet = PahoMqtt::Packet::Unsubscribe.new(
|
117
|
+
:id => new_id,
|
118
|
+
:topics => topics
|
119
|
+
)
|
120
|
+
|
121
|
+
@sender.append_to_writing(packet)
|
122
|
+
@unsuback_mutex.synchronize {
|
123
|
+
@waiting_unsuback.push({:id => new_id, :packet => packet, :timestamp => Time.now})
|
124
|
+
}
|
125
|
+
MQTT_ERR_SUCCESS
|
126
|
+
else
|
127
|
+
raise ProtocolViolation
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def check_waiting_subscriber
|
132
|
+
@sender.check_ack_alive(@waiting_suback, @suback_mutex, @waiting_suback.length)
|
133
|
+
@sender.check_ack_alive(@waiting_unsuback, @unsuback_mutex, @waiting_unsuback.length)
|
134
|
+
end
|
135
|
+
|
136
|
+
def valid_topics?(topics)
|
137
|
+
unless topics.length == 0
|
138
|
+
topics.map do |topic|
|
139
|
+
return MQTT_ERR_FAIL if topic.first == ""
|
140
|
+
end
|
141
|
+
else
|
142
|
+
MQTT_ERR_FAIL
|
143
|
+
end
|
144
|
+
MQTT_ERR_SUCCESS
|
145
|
+
end
|
146
|
+
|
147
|
+
|
148
|
+
private
|
149
|
+
|
150
|
+
def match_filter(topics, filters)
|
151
|
+
check_topics(topics, filters)
|
152
|
+
index = 0
|
153
|
+
rc = false
|
154
|
+
topic = topics.split('/')
|
155
|
+
filter = filters.split('/')
|
156
|
+
while index < [topic.length, filter.length].max do
|
157
|
+
if is_end?(topic[index], filter[index])
|
158
|
+
break
|
159
|
+
elsif is_wildcard?(filter[index])
|
160
|
+
rc = index == (filter.length - 1)
|
161
|
+
break
|
162
|
+
elsif keep_running?(filter[index], topic[index])
|
163
|
+
index = index + 1
|
164
|
+
else
|
165
|
+
break
|
166
|
+
end
|
167
|
+
end
|
168
|
+
is_matching?(rc, topic.length, filter.length, index)
|
169
|
+
end
|
170
|
+
|
171
|
+
def keep_running?(filter_part, topic_part)
|
172
|
+
filter_part == topic_part || filter_part == '+'
|
173
|
+
end
|
174
|
+
|
175
|
+
def is_wildcard?(filter_part)
|
176
|
+
filter_part == '#'
|
177
|
+
end
|
178
|
+
|
179
|
+
def is_end?(topic_part, filter_part)
|
180
|
+
topic_part.nil? || filter_part.nil?
|
181
|
+
end
|
182
|
+
|
183
|
+
def is_matching?(rc, topic_length, filter_length, index)
|
184
|
+
rc || index == [topic_length, filter_length].max
|
185
|
+
end
|
186
|
+
|
187
|
+
def check_topics(topics, filters)
|
188
|
+
if topics.is_a?(String) && filters.is_a?(String)
|
189
|
+
else
|
190
|
+
@logger.error("Topics or Wildcards are not found as String.") if logger?
|
191
|
+
raise ArgumentError
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|