xively / mosquitto

Ruby binding against libmosquitto (http://mosquitto.org/) - a high performance MQTT protocol (http://mqtt.org) client
Other
58 stars 16 forks source link

subscribe / on_subscribe #14

Open dramalho opened 10 years ago

dramalho commented 10 years ago

Hi

quick check, maybe I'm being an idiot here :)

I'm using them gem to connect to a mosquitto instance running locally . I'm building a bunch of agent that will be running for a while so I'm trying to be somewhat resilient here and because everything runs asynchronously, so I have, for instance, a callback on on_connect to flush any topic subscriptions that other parts of the agent might have requested before mosquitto was actually connected.

For that, and following the documentation, I'm assigning each topic a numerical id that I provide when subscribing to the topic, I then have a callback block on on_subscribe that I would use to mark a certain topic as subscribed (and if for some reason flush_topics would need to run again, I would skip those)

Anyway, my issue is I'm assigning topic subscription an id, but the callback responds with a completely different number, so I can't match both .

Some code might help here :) , this is a simplification of what I'm doing, but it's fine


require 'mosquitto'

mqtt_host = 'localhost'
mqtt_port = 1883
client_id = Process.pid.to_s

mqtt = Mosquitto::Client.new # default options

subscribed_topics = [
  {topic: 'topic_1', subscribed: false},
  {topic: 'topic_2', subscribed: false},
  {topic: 'topic_3', subscribed: false},
]

mqtt.on_connect do |_|
  puts 'Mqtt on_connect'

  # flush topics
  subscribed_topics.each_with_index do |t, k|
    puts "Subscribing to #{t[:topic]} with mid #{k+100}"
    mqtt.subscribe(k + 100, t[:topic], Mosquitto::AT_LEAST_ONCE) unless t[:subscribed]
  end  
end

mqtt.on_subscribe do |mid, qos|
  puts "Mqtt on_subscribe: #{mid} -> #{qos}"
  subscribed_topics[mid][:subscribed] = true if subscribed_topics[mid]
end

mqtt.loop_start
mqtt.connect_async(mqtt_host, mqtt_port, 10)

and this outputs the following

Mqtt on_connect
Subscribing to topic_1 with mid 100
Subscribing to topic_2 with mid 101
Subscribing to topic_3 with mid 102
Mqtt on_subscribe: 1 -> [0]
Mqtt on_subscribe: 3 -> [0]
Mqtt on_subscribe: 2 -> [0]

Now, my expectation from the documentation on subscribe and on_subscribe would be that the mid was there to achieve this sort of async matching, but the behaviour seems to indicate that the subscribe method is ignoring the given mid and applying a sequencial mid that the on_subscribe then reports (or something) :)

dramalho commented 10 years ago

oh, and I'm using mosquitto (0.3)

dramalho commented 10 years ago

oh, and the qos argument on on_subscribe that should be returning an Array of QOS values, it never returns an array, and ocasionally I do get the odd number

Mqtt on_subscribe: 1 -> [0]
Mqtt on_subscribe: 2 -> [-222987343]
Mqtt on_subscribe: 3 -> [0]

This after running the exemple above a couple of times, o leaving it to reconnect :)

Also, I'm running mosquitto version 1.3.1 (build date 2014-04-09 11:47:29+0100) on a Mac :)

Again, maybe I'm being an idiot somewhere and this is not so much a lib problem, but either way, just wanted to bounce some ideas off you :)

thanks

methodmissing commented 10 years ago

Thanks for all the great context @dramalho - will take a look shortly ...

dramalho commented 10 years ago

awesome, thanks :)

dramalho commented 10 years ago

It seems like I'm getting the same behaviour from publish / on_publish

require 'mosquitto'

mqtt_host = 'localhost'
mqtt_port = 1883
client_id = Process.pid.to_s

mqtt = Mosquitto::Client.new # default options

mqtt.on_connect do |_|
  puts 'Mqtt on_connect'

  %w(msg1 msg2 msg3).each_with_index do |msg, idx|
    puts "Publishing #{msg} to topic test with mid #{idx+100}"
    mqtt.publish(idx + 100, msg, 'test', Mosquitto::AT_MOST_ONCE, false)
  end
end

mqtt.on_publish do |mid|
  puts "Published message with mid #{mid}"
end

mqtt.loop_start
mqtt.connect_async(mqtt_host, mqtt_port, 10)

outputs

 Mqtt on_connect
Publishing msg1 to topic test with mid 100
Publishing msg2 to topic test with mid 101
Publishing msg3 to topic test with mid 102
Published message with mid 3
Published message with mid 2
Published message with mid 1
jsaak commented 9 years ago

mosquitto is generating the message id-s i do not think you can pass it a custom one the library has to give that back to you like:

message_id = mqtt.publish(msg, 'test', Mosquitto::AT_MOST_ONCE, false)

this message_id will be the same as in the on_publish callback (that is why in the c code you do pass mid as a reference)

additionally you should see

Published message with mid 1
Published message with mid 2
Published message with mid 3

i do not know why it is in a reversed order