mqtt-sub_handler 0.1.6.2 → 0.1.6.10

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA256:
3
- metadata.gz: bfe901d34d1a891840006f77467ef0929bfb9ff1363ccc3ece47cf35454178b0
4
- data.tar.gz: 1e601e44349b5e360068d3e07a4a59caa0254cfc2aaee1e1f870fe1069041e96
2
+ SHA1:
3
+ metadata.gz: 35fd43af3792d80dd5b218ad0b3e55c61c4d750d
4
+ data.tar.gz: afd508d2b76d30428d3c6c74ad44f12a7428b123
5
5
  SHA512:
6
- metadata.gz: 589b2c0307aa5ec6aa0e253805d8b095ce73997bd9461bc7abc060d306ac6f1b5c8ff18ddee861a1c2d43d6b7e3685bacb9b4994360b106c1ad19791c91bd511
7
- data.tar.gz: 4d5d90483bfa7ce80c4c6359d5fb38faad29a08f447d987cebf1779597190c4e7d692950a0bafa1d63b98d5d76d5fcdedd696b6385ab170a5c917da0c4ef0ac0
6
+ metadata.gz: ec4ef80c35649a5ed3c56666d7797c9436a2f5aba2e02bfeea433c01be85e5343d7a5fb68fab03fde76953a1787527929ccf1f8f74138fb2913846901e21c3b6
7
+ data.tar.gz: '0200581a1aa3da0d1a33519d725e3b0d5c987fd54f6e9466e69f8638de2a3844abab71ba4384a8121539e03889961fe201977086a319ad2147c4516b0956e27c'
@@ -0,0 +1,353 @@
1
+
2
+ require 'timeout'
3
+ require 'mqtt'
4
+ require 'colorize'
5
+
6
+ require 'xasin_logger'
7
+
8
+ module MQTT
9
+ class BaseHandler
10
+ include XasLogger::Mix
11
+
12
+ # Split a Topic into a Topic-Array
13
+ # @param topicName [String] The string topic which to split
14
+ # @return [Array<String>] A list of individual topic-branches
15
+ # @note This function is mainly used for background processing.
16
+ def self.get_topic_split(topicName)
17
+ return topicName.scan(/[^\/]+/);
18
+ end
19
+
20
+ # Match a topic string to a topic pattern
21
+ # @param receivedTopicString [String] The string (as
22
+ # returned by MQTT.get) to compare
23
+ # @param topicPattern [Array<String>] The Topic-Array (as
24
+ # returned by .get_topic_split) to compare against
25
+ # @return [nil, Array<String>] Nil if no match was found.
26
+ # An Array of matched wildcard topic branches (can be empty) when
27
+ # successfully matched
28
+ # @note (see .get_topic_split)
29
+ def self.getTopicMatch(receivedTopicString, topicPattern)
30
+ receivedTopicList = get_topic_split receivedTopicString;
31
+
32
+ outputTopicList = Array.new();
33
+
34
+ return nil unless receivedTopicList.length >= topicPattern.length;
35
+
36
+ topicPattern.each_index do |i|
37
+ if(topicPattern[i] == "+")
38
+ outputTopicList << receivedTopicList[i];
39
+
40
+ elsif(topicPattern[i] == "#")
41
+ outputTopicList.concat receivedTopicList[i..-1];
42
+ return outputTopicList;
43
+
44
+ elsif topicPattern[i] != receivedTopicList[i];
45
+ return nil;
46
+
47
+ end
48
+ end
49
+
50
+ return outputTopicList if topicPattern.length == receivedTopicList.length;
51
+ return nil;
52
+ end
53
+
54
+ # Call all existing callbacks whose topic-list matches `topic`
55
+ def call_interested(topic, data)
56
+ topicHasReceivers = false;
57
+ @callbackList.each do |h|
58
+ tMatch = BaseHandler.getTopicMatch(topic, h.topic_split);
59
+ if tMatch
60
+ begin
61
+ Timeout.timeout(10) {
62
+ h.offer(tMatch, data)
63
+ }
64
+ rescue Timeout::Error
65
+ x_loge("Timeout on callback #{h}");
66
+ rescue => e
67
+ x_logf("Uncaught error on #{h}");
68
+ x_logf(e.inspect);
69
+ end
70
+ topicHasReceivers = true;
71
+ end
72
+ end
73
+
74
+ @mqtt.unsubscribe(topic) unless topicHasReceivers;
75
+ end
76
+ private :call_interested
77
+
78
+ def queue_packet(data)
79
+ return if @destroying
80
+
81
+ @packetQueueMutex.synchronize {
82
+ @packetQueue << data;
83
+ if(@packetQueue.size == 999)
84
+ x_logf("Packet queue congested, dropping packets!");
85
+ end
86
+ if(@packetQueue.size > 1000)
87
+ @packetQueue.shift
88
+ end
89
+
90
+ @publisherThread.run() if @publisherThreadWaiting;
91
+ }
92
+ end
93
+ private :queue_packet
94
+
95
+ # @!group Custom subscription handling
96
+
97
+ # Unregister a subscription. Removes it from the callback list and
98
+ # unsubscribes from the topic if no other subscriptions for it are present.
99
+ # @param subObject [MQTT::Subscriptions::Subscription]
100
+ # The subscription-object to remove
101
+ # @return void
102
+ def unregister_subscription(subObject)
103
+ raise ArgumentError, "Object is not a subscription!" unless subObject.is_a? MQTT::Subscriptions::Subscription
104
+ return unless @callbackList.include? subObject;
105
+
106
+ queue_packet({type: :unsub, topic: subObject.topic});
107
+ @callbackList.delete(subObject);
108
+ end
109
+ # Register a custom subscription, and send a subscription message to the server.
110
+ # @param subObject [MQTT::Subscriptions::Subscription]
111
+ # An instance of a MQTT Subscription object
112
+ # @return void
113
+ def register_subscription(subObject)
114
+ raise ArgumentError, "Object is not a subscription!" unless subObject.is_a? MQTT::Subscriptions::Subscription
115
+ return if @callbackList.include? subObject;
116
+
117
+ @callbackList << subObject;
118
+ queue_packet({type: :sub, topic: subObject.topic, qos: subObject.qos});
119
+ end
120
+
121
+ # @!endgroup
122
+
123
+ def ensure_clean_start()
124
+ @mqttWasStartedClean = @mqtt.clean_session
125
+ if @mqttWasStartedClean
126
+ begin
127
+ @mqtt.connect();
128
+ @mqtt.disconnect();
129
+ rescue MQTT::Exception
130
+ sleep 1;
131
+ retry
132
+ rescue SocketError, SystemCallError
133
+ sleep 5
134
+ retry
135
+ end
136
+ @mqtt.clean_session=false;
137
+ end
138
+ end
139
+ private :ensure_clean_start
140
+
141
+ def ensure_clean_exit()
142
+ if(@mqttWasStartedClean)
143
+ x_logi("Logging out.")
144
+ begin
145
+ Timeout.timeout(3) {
146
+ begin
147
+ @mqtt.clean_session = true;
148
+ @mqtt.disconnect();
149
+ @mqtt.connect();
150
+ rescue MQTT::Exception, SocketError, SystemCallError
151
+ sleep 0.3
152
+ retry;
153
+ end
154
+ }
155
+ rescue Timeout::Error
156
+ x_loge("Timed out, aborting!");
157
+ else
158
+ x_logi("Done");
159
+ end
160
+ end
161
+ end
162
+ private :ensure_clean_exit
163
+
164
+ def attempt_packet_publish()
165
+ until @packetQueue.empty? do
166
+ h = nil;
167
+ @packetQueueMutex.synchronize {
168
+ h = @packetQueue[0];
169
+ }
170
+ Timeout.timeout(3) {
171
+ if(h[:type] == :sub)
172
+ @mqtt.subscribe(h[:topic] => h[:qos]);
173
+ elsif(h[:type] == :pub)
174
+ @mqtt.publish(h[:topic], h[:data], h[:retain], h[:qos]);
175
+ end
176
+ }
177
+ @packetQueueMutex.synchronize {
178
+ @packetQueue.shift();
179
+ }
180
+ end
181
+ end
182
+
183
+ def mqtt_push_thread
184
+ @push_error_count = 0;
185
+
186
+ loop do
187
+ @packetQueueMutex.synchronize {
188
+ @publisherThreadWaiting = true;
189
+ }
190
+ x_logd("Push thread stopping")
191
+ sleep 1
192
+ x_logd("Push thread active")
193
+ @packetQueueMutex.synchronize {
194
+ @publisherThreadWaiting = false;
195
+ }
196
+ break if @destroying
197
+
198
+ next unless @connected
199
+
200
+ begin
201
+ attempt_packet_publish();
202
+ rescue MQTT::Exception, SocketError, SystemCallError, Timeout::Error => e
203
+ x_loge("Push error!");
204
+ x_loge(e.inspect);
205
+
206
+ @push_error_count += 1;
207
+ if(@push_error_count >= 10)
208
+ @mqtt.disconnect();
209
+ end
210
+
211
+ sleep 0.5
212
+ else
213
+ @push_error_count = 0;
214
+ end
215
+ end
216
+
217
+ x_logd("Push thread exited!");
218
+ end
219
+ private :mqtt_push_thread
220
+
221
+ def mqtt_resub_thread
222
+ loop do
223
+ begin
224
+ return if @destroying
225
+
226
+ x_logw("Trying to reconnect...");
227
+ Timeout.timeout(4) {
228
+ @mqtt.connect()
229
+ }
230
+ x_logi("Connected!");
231
+ @conChangeMutex.synchronize {
232
+ @connected = true;
233
+ @reconnectCount = 0;
234
+ }
235
+
236
+ @packetQueueMutex.synchronize {
237
+ @publisherThread.run() if (@publisherThread && @publisherThreadWaiting)
238
+ }
239
+
240
+ x_logd("Sub thread reading...");
241
+ @mqtt.get do |topic, message|
242
+ call_interested(topic, message);
243
+ end
244
+ rescue MQTT::Exception, Timeout::Error, SocketError, SystemCallError
245
+ x_loge("Disconnected!") if @connected
246
+ @connected = false;
247
+ @reconnectCount += 1;
248
+
249
+ @conChangeMutex.unlock if @conChangeMutex.owned?
250
+ @mqtt.clean_session = false;
251
+ sleep [0.1, 0.5, 1, 1, 5, 5, 5, 10, 10, 10, 10][@reconnectCount] || 30;
252
+ end
253
+ end
254
+
255
+ x_logd("Sub thread exited");
256
+ end
257
+ private :mqtt_resub_thread
258
+
259
+ def destroy!()
260
+ return if @destroying
261
+ @destroying = true;
262
+
263
+ unless @packetQueue.empty?
264
+ x_logd "Finishing sending of MQTT messages ... "
265
+ @publisherThread.run() if @publisherThreadWaiting
266
+ begin
267
+ Timeout.timeout(4) {
268
+ until @packetQueue.empty? do
269
+ sleep 0.05;
270
+ end
271
+ }
272
+ rescue Timeout::Error
273
+ x_logw "Not all messages were published";
274
+ else
275
+ x_logd "Publish clean finished"
276
+ end
277
+ end
278
+
279
+ @publisherThread.run();
280
+ @publisherThread.join();
281
+ @listenerThread.kill();
282
+
283
+ @mqtt.disconnect() if @connected
284
+
285
+ ensure_clean_exit();
286
+
287
+ x_logi("Fully disconnected!");
288
+ end
289
+
290
+ # Initialize a new MQTT::SubHandler
291
+ # The handler immediately connects to the server, and begins receciving and sending.
292
+ # @param mqttClient [String, MQTT::Client] Either a URI to connect to, or a MQTT::Client
293
+ # The URI can be of the form "mqtts://Password@User:URL:port".
294
+ # The MQTT client instance can be fully configured, as specified by the MQTT Gem. It must *not* already be connected!
295
+ # @param jsonify [Boolean] Should Hashes and Arrays input into publish_to be converted to JSON?
296
+ # This can be useful to have one less .to_json call. Default is true.
297
+ # @example Starting the handler
298
+ # mqtt = MQTT::SubHandler.new('mqtt.eclipse.org');
299
+ # mqtt = MQTT::SubHandler.new(MQTT::Client.new("Your.Client.Opts"))
300
+ def initialize(mqttClient, logger: nil, **extra_opts)
301
+ @callbackList = Array.new();
302
+ if mqttClient.is_a? String
303
+ @mqtt = MQTT::Client.new(mqttClient);
304
+ @mqtt.clean_session = false unless extra_opts[:client_id].nil?
305
+ else
306
+ @mqtt = mqttClient;
307
+ end
308
+
309
+ init_x_log("MQTT #{@mqtt.host}", logger);
310
+ self.log_level = Logger::INFO;
311
+
312
+ @conChangeMutex = Mutex.new();
313
+ @connected = false;
314
+ @reconnectCount = 0;
315
+
316
+ @mqtt.client_id ||= extra_opts[:client_id] || MQTT::Client.generate_client_id("MQTT_Sub_", 8);
317
+
318
+ @packetQueue = Array.new();
319
+ @packetQueueMutex = Mutex.new();
320
+
321
+ @publisherThreadWaiting = false;
322
+
323
+ @subscribedTopics = Hash.new();
324
+
325
+ @trackerHash = Hash.new();
326
+
327
+ @listenerThread = Thread.new do
328
+ ensure_clean_start();
329
+ mqtt_resub_thread();
330
+ end
331
+ @listenerThread.abort_on_exception = true;
332
+
333
+ begin
334
+ Timeout.timeout(5) {
335
+ until(@connected)
336
+ sleep 0.1;
337
+ end
338
+ }
339
+ rescue Timeout::Error
340
+ x_loge("Broker did not connect!");
341
+ end
342
+
343
+ @publisherThread = Thread.new do
344
+ mqtt_push_thread();
345
+ end
346
+ @publisherThread.abort_on_exception = true;
347
+
348
+ at_exit {
349
+ destroy!()
350
+ }
351
+ end
352
+ end
353
+ end
@@ -1,129 +1,24 @@
1
1
 
2
- require 'timeout'
3
- require 'mqtt'
4
- require 'json'
5
2
 
6
- require 'colorize'
3
+ require 'json'
7
4
 
8
5
  require_relative 'subscription_classes.rb'
6
+ require_relative 'base_handler.rb'
9
7
 
10
8
  # @author Xasin
11
9
  module MQTT
12
10
  # A shortcut-function to quickly connect to the public Eclipse MQTT Broker.
13
- # @return [MQTT::SubHandler] Sub-Handler connected to `iot.eclipse.org`
11
+ # @return [MQTT::SubHandler] Sub-Handler connected to `mqtt.eclipse.org`
14
12
  def self.Eclipse()
15
- @EclipseMQTT ||= SubHandler.new('iot.eclipse.org');
13
+ @EclipseMQTT ||= SubHandler.new('mqtt.eclipse.org');
16
14
  return @EclipseMQTT;
17
15
  end
18
16
 
19
17
 
20
- class SubHandler
18
+ class SubHandler < BaseHandler
21
19
  # Whether or not hashes and arrays should be converted to JSON when sending
22
20
  attr_accessor :jsonifyHashes
23
21
 
24
- # Split a Topic into a Topic-Array
25
- # @param topicName [String] The string topic which to split
26
- # @return [Array<String>] A list of individual topic-branches
27
- # @note This function is mainly used for background processing.
28
- def self.get_topic_split(topicName)
29
- return topicName.scan(/[^\/]+/);
30
- end
31
-
32
- # Match a topic string to a topic pattern
33
- # @param receivedTopicString [String] The string (as
34
- # returned by MQTT.get) to compare
35
- # @param topicPattern [Array<String>] The Topic-Array (as
36
- # returned by .get_topic_split) to compare against
37
- # @return [nil, Array<String>] Nil if no match was found.
38
- # An Array of matched wildcard topic branches (can be empty) when
39
- # successfully matched
40
- # @note (see .get_topic_split)
41
- def self.getTopicMatch(receivedTopicString, topicPattern)
42
- receivedTopicList = get_topic_split receivedTopicString;
43
-
44
- outputTopicList = Array.new();
45
-
46
- return nil unless receivedTopicList.length >= topicPattern.length;
47
-
48
- topicPattern.each_index do |i|
49
- if(topicPattern[i] == "+")
50
- outputTopicList << receivedTopicList[i];
51
-
52
- elsif(topicPattern[i] == "#")
53
- outputTopicList.concat receivedTopicList[i..-1];
54
- return outputTopicList;
55
-
56
- elsif topicPattern[i] != receivedTopicList[i];
57
- return nil;
58
-
59
- end
60
- end
61
-
62
- return outputTopicList if topicPattern.length == receivedTopicList.length;
63
- return nil;
64
- end
65
-
66
- # Call all existing callbacks whose topic-list matches `topic`
67
- def call_interested(topic, data)
68
- topicHasReceivers = false;
69
- @callbackList.each do |h|
70
- tMatch = SubHandler.getTopicMatch(topic, h.topic_split);
71
- if tMatch
72
- begin
73
- Timeout.timeout(5) {
74
- h.offer(tMatch, data)
75
- }
76
- rescue Timeout::Error
77
- STDERR.puts "MQTT: Callback Timeout #{h}".red
78
- end
79
- topicHasReceivers = true;
80
- end
81
- end
82
-
83
- @mqtt.unsubscribe(topic) unless topicHasReceivers;
84
- end
85
- private :call_interested
86
-
87
- def queue_packet(data)
88
- @packetQueueMutex.synchronize {
89
- @packetQueue << data;
90
- @packetQueue.shift if @packetQueue.size > 100
91
-
92
- @publisherThread.run() if @publisherThreadWaiting;
93
- }
94
- end
95
-
96
- # Handle sending a subscription-message to the server
97
- def raw_subscribe_to(topic, qos: 1)
98
- queue_packet({topic: topic, qos: qos, type: :sub});
99
- end
100
- private :raw_subscribe_to
101
-
102
- # @!group Custom subscription handling
103
-
104
- # Unregister a subscription. Removes it from the callback list and
105
- # unsubscribes from the topic if no other subscriptions for it are present.
106
- # @param subObject [MQTT::Subscriptions::Subscription]
107
- # The subscription-object to remove
108
- # @return void
109
- def unregister_subscription(subObject)
110
- raise ArgumentError, "Object is not a subscription!" unless subObject.is_a? MQTT::Subscriptions::Subscription
111
- return unless @callbackList.include? subObject;
112
-
113
- @callbackList.delete(subObject);
114
- end
115
- # Register a custom subscription, and send a subscription message to the server.
116
- # @param subObject [MQTT::Subscriptions::Subscription]
117
- # An instance of a MQTT Subscription object
118
- # @return void
119
- def register_subscription(subObject)
120
- raise ArgumentError, "Object is not a subscription!" unless subObject.is_a? MQTT::Subscriptions::Subscription
121
- return if @callbackList.include? subObject;
122
-
123
- @callbackList << subObject;
124
- raw_subscribe_to(subObject.topic, qos: subObject.qos);
125
- end
126
-
127
22
  # @!group Subscribing
128
23
 
129
24
  # Synchronously wait for data.
@@ -221,8 +116,7 @@ class SubHandler
221
116
 
222
117
  if(qos > 1)
223
118
  qos = 1
224
- STDERR.puts("MQTT push with QOS > 1 was attempted, this is not supported yet!".yellow) unless $MQTTPubQOSWarned
225
-
119
+ x_logw("push with QOS > 1 was attempted, this is not supported yet!") unless $MQTTPubQOSWarned
226
120
  $MQTTPubQOSWarned = true;
227
121
  end
228
122
 
@@ -230,117 +124,6 @@ class SubHandler
230
124
  end
231
125
  alias publishTo publish_to
232
126
 
233
- def ensure_clean_start()
234
- @mqttWasStartedClean = @mqtt.clean_session
235
- if @mqttWasStartedClean
236
- begin
237
- @mqtt.connect();
238
- @mqtt.disconnect();
239
- rescue MQTT::Exception
240
- sleep 1;
241
- retry
242
- rescue SocketError, SystemCallError
243
- sleep 5
244
- retry
245
- end
246
- @mqtt.clean_session=false;
247
- end
248
- end
249
- private :ensure_clean_start
250
-
251
- def ensure_clean_exit()
252
- if(@mqttWasStartedClean)
253
- print "Logging out of mqtt server... "
254
- begin
255
- Timeout.timeout(3) {
256
- begin
257
- @mqtt.clean_session = true;
258
- @mqtt.disconnect();
259
- @mqtt.connect();
260
- rescue MQTT::Exception, SocketError, SystemCallError
261
- sleep 0.3
262
- retry;
263
- end
264
- }
265
- rescue Timeout::Error
266
- puts "Timed out, aborting!";
267
- else
268
- puts "Done."
269
- end
270
- end
271
- end
272
- private :ensure_clean_exit
273
-
274
- def mqtt_push_thread
275
- loop do
276
- @packetQueueMutex.synchronize {
277
- @publisherThreadWaiting = true;
278
- }
279
- Thread.stop();
280
- @packetQueueMutex.synchronize {
281
- @publisherThreadWaiting = false;
282
- }
283
-
284
- next unless @connected
285
-
286
- begin
287
- until @packetQueue.empty? do
288
- h = nil;
289
- @packetQueueMutex.synchronize {
290
- h = @packetQueue[0];
291
- }
292
- Timeout.timeout(3) {
293
- if(h[:type] == :sub)
294
- @mqtt.subscribe(h[:topic] => h[:qos]);
295
- elsif(h[:type] == :pub)
296
- @mqtt.publish(h[:topic], h[:data], h[:retain], h[:qos]);
297
- end
298
- }
299
- @packetQueueMutex.synchronize {
300
- @packetQueue.shift();
301
- }
302
- end
303
- rescue MQTT::Exception, SocketError, SystemCallError, Timeout::Error => e
304
- STDERR.puts("MQTT: #{@mqtt.host} push error, disconnecting!".red) if @connected
305
- STDERR.puts(e.inspect);
306
-
307
- sleep 1
308
- end
309
- end
310
- end
311
- private :mqtt_push_thread
312
-
313
- def mqtt_resub_thread
314
- loop do
315
- begin
316
- STDERR.puts("MQTT: #{@mqtt.host} trying reconnect...".yellow)
317
- Timeout.timeout(4) {
318
- @mqtt.connect()
319
- }
320
- STDERR.puts("MQTT: #{@mqtt.host} connected!".green)
321
- @conChangeMutex.synchronize {
322
- @connected = true;
323
- }
324
-
325
- @packetQueueMutex.synchronize {
326
- @publisherThread.run() if (@publisherThread && @publisherThreadWaiting)
327
- }
328
-
329
- @mqtt.get do |topic, message|
330
- call_interested(topic, message);
331
- end
332
- rescue MQTT::Exception, Timeout::Error, SocketError, SystemCallError
333
- STDERR.puts("MQTT: #{@mqtt.host} disconnected!".red) if @connected
334
- @connected = false;
335
-
336
- @conChangeMutex.unlock if @conChangeMutex.owned?
337
- @mqtt.clean_session = false;
338
- sleep 2
339
- end
340
- end
341
- end
342
- private :mqtt_resub_thread
343
-
344
127
  # Pause the main thread and wait for messages.
345
128
  # This is mainly useful when the code has set everything up, but doesn't just want to end.
346
129
  # "INT" is trapped, ensuring a smooth exit on Ctrl-C
@@ -349,87 +132,15 @@ class SubHandler
349
132
  exit 0
350
133
  }
351
134
 
352
- puts "Main thread paused."
135
+ x_logi("Main thread paused.")
353
136
  Thread.stop();
354
137
  end
355
- def flush_pubqueue()
356
- unless @packetQueue.empty?
357
- print "Finishing sending of MQTT messages ... "
358
- begin
359
- Timeout.timeout(4) {
360
- until @packetQueue.empty? do
361
- sleep 0.05;
362
- end
363
- }
364
- rescue Timeout::Error
365
- puts "Timed out, aborting."
366
- else
367
- puts "Done."
368
- end
369
- end
370
- end
371
- private :flush_pubqueue
138
+ alias lock_and_listen lockAndListen
372
139
 
373
- # Initialize a new MQTT::SubHandler
374
- # The handler immediately connects to the server, and begins receciving and sending.
375
- # @param mqttClient [String, MQTT::Client] Either a URI to connect to, or a MQTT::Client
376
- # The URI can be of the form "mqtts://Password@User:URL:port".
377
- # The MQTT client instance can be fully configured, as specified by the MQTT Gem. It must *not* already be connected!
378
- # @param jsonify [Boolean] Should Hashes and Arrays input into publish_to be converted to JSON?
379
- # This can be useful to have one less .to_json call. Default is true.
380
- # @example Starting the handler
381
- # mqtt = MQTT::SubHandler.new('iot.eclipse.org');
382
- # mqtt = MQTT::SubHandler.new(MQTT::Client.new("Your.Client.Opts"))
383
- def initialize(mqttClient, jsonify: true)
384
- @callbackList = Array.new();
385
- if mqttClient.is_a? String
386
- @mqtt = MQTT::Client.new(mqttClient);
387
- else
388
- @mqtt = mqttClient;
389
- end
140
+ def initialize(mqttClient, jsonify: true, **extra_opts)
141
+ super(mqttClient, **extra_opts);
390
142
 
391
143
  @jsonifyHashes = jsonify;
392
-
393
- @conChangeMutex = Mutex.new();
394
- @connected = false;
395
-
396
- @mqtt.client_id ||= MQTT::Client.generate_client_id("MQTT_Sub_", 8);
397
-
398
- @packetQueue = Array.new();
399
- @packetQueueMutex = Mutex.new();
400
- @publisherThreadWaiting = false;
401
-
402
- @subscribedTopics = Hash.new();
403
-
404
- @trackerHash = Hash.new();
405
-
406
- @listenerThread = Thread.new do
407
- ensure_clean_start();
408
- mqtt_resub_thread();
409
- end
410
- @listenerThread.abort_on_exception = true;
411
-
412
- begin
413
- Timeout.timeout(5) {
414
- until(@connected)
415
- sleep 0.1;
416
- end
417
- }
418
- rescue Timeout::Error
419
- STDERR.puts "MQTT: #{@mqtt.host} did not connect!".red
420
- end
421
-
422
- @publisherThread = Thread.new do
423
- mqtt_push_thread();
424
- end
425
- @publisherThread.abort_on_exception = true;
426
-
427
- at_exit {
428
- flush_pubqueue();
429
- @connected = false;
430
- @listenerThread.kill();
431
- ensure_clean_exit();
432
- }
433
144
  end
434
145
  end
435
146
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mqtt-sub_handler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6.2
4
+ version: 0.1.6.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Xasin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-10-06 00:00:00.000000000 Z
11
+ date: 2021-01-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mqtt
@@ -28,30 +28,30 @@ dependencies:
28
28
  name: json
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: '2.2'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: '2.2'
41
41
  - !ruby/object:Gem::Dependency
42
- name: colorize
42
+ name: xasin-logger
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
47
+ version: '0.1'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ">="
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '0'
54
+ version: '0.1'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: minitest
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -103,6 +103,7 @@ extra_rdoc_files: []
103
103
  files:
104
104
  - README.md
105
105
  - lib/mqtt/Waitpoint.rb
106
+ - lib/mqtt/base_handler.rb
106
107
  - lib/mqtt/mqtt_hash.rb
107
108
  - lib/mqtt/persistence.rb
108
109
  - lib/mqtt/persistence_extensions.rb
@@ -128,7 +129,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
128
129
  - !ruby/object:Gem::Version
129
130
  version: '0'
130
131
  requirements: []
131
- rubygems_version: 3.0.6
132
+ rubyforge_project:
133
+ rubygems_version: 2.5.2.1
132
134
  signing_key:
133
135
  specification_version: 4
134
136
  summary: Asynchronous, topic-based MQTT gem