njh / ruby-mqtt Goto Github PK
View Code? Open in Web Editor NEWPure Ruby gem that implements the MQTT protocol, a lightweight protocol for publish/subscribe messaging.
Home Page: http://www.rubydoc.info/gems/mqtt
License: MIT License
Pure Ruby gem that implements the MQTT protocol, a lightweight protocol for publish/subscribe messaging.
Home Page: http://www.rubydoc.info/gems/mqtt
License: MIT License
it currently takes array or arrays for some reason :(
I test a sample code and set QOS to 1. Why is the server is always sending the message to the subscribe client even the subscribe client already received the message and as I search #58 this should solve the problem because in MQTT specs the subscribe client should send PUBACK after receiving the message to tag that message is received. Did I missed something? Any tips?
sub.rb
require 'rubygems'
require 'mqtt'
MQTT::Client.connect('192.168.9.105') do |client|
client.get_packet('test'=>1) do |packet|
puts packet.inspect
end
end
pub.rb
require 'rubygems'
require 'mqtt'
# Publish example
MQTT::Client.connect('192.168.9.105') do |c|
c.publish('test', 'message 3', 0, 1)
end
Doing this hangs:
mqtt_client.connect do |c|
c.get("/#") do |topic,message|
# Oh no, hangs forever
end
c.disconnect
end
but doing this works for exactly one message:
mqtt_client.connect do |c|
topic, message = c.get("/#")
c.disconnect
end
This is very confusing when writing specs
Running this under Ruby 2.0.0 on Cloud Foundry talking to iot.eclipse.org
I occasionally encounter:
2014-03-03T16:18:45.63+0000 [App/3] ERR /home/vcap/app/vendor/bundle/ruby/2.0.0/gems/mqtt-0.1.0/lib/mqtt/client.rb:305:in `select': no implicit conversion of nil into IO (TypeError)
2014-03-03T16:18:45.63+0000 [App/3] ERR from /home/vcap/app/vendor/bundle/ruby/2.0.0/gems/mqtt-0.1.0/lib/mqtt/client.rb:305:in `receive_packet'
2014-03-03T16:18:45.63+0000 [App/3] ERR from /home/vcap/app/vendor/bundle/ruby/2.0.0/gems/mqtt-0.1.0/lib/mqtt/client.rb:151:in `block (2 levels) in connect'
2014-03-03T16:18:45.63+0000 [App/3] ERR from /home/vcap/app/vendor/bundle/ruby/2.0.0/gems/mqtt-0.1.0/lib/mqtt/client.rb:151:in `loop'
2014-03-03T16:18:45.63+0000 [App/3] ERR from /home/vcap/app/vendor/bundle/ruby/2.0.0/gems/mqtt-0.1.0/lib/mqtt/client.rb:151:in `block in connect'
Given
MQTT::Client.new('mqtt://user:[email protected]:13858').connect
the library assumes a default port of 1883; even though I've specified something different.
Exception during check: Connection refused - connect(2) for "m10.cloudmqtt.com" port 1883 -- [
"/home/clockwerx/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/mqtt-0.2.0/lib/mqtt/client.rb:234:in `initialize'",
"/home/clockwerx/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/mqtt-0.2.0/lib/mqtt/client.rb:234:in `new'",
"/home/clockwerx/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/mqtt-0.2.0/lib/mqtt/client.rb:234:in `connect'",
...
]
It looks like there hasn't been a release since October 2014. It might be time to push v0.4.0. ๐
when not enough buffer is available
The client does not seem to support URI connections. While there is no common MQTT URI scheme, suporting mqtt://
and tcp://
URI's would make it easier to
use this client in PaaS environments (Heroku, Cloud Foundry, OpenShift, โฆ) that primarily expose credentials as URI's.
Types of storage for persistence:
I am not sure if it would be possible to use Memcache - I think a key quality would be to iterate through the persisted messages.
This is a pre-requisite for QoS 1 and 2.
Thank you for the library!
Could it be possible to remove the test for the length of the client ID?
Some MQTT cloud services (like IBM's Internet of things Cloud) are implementing the new standard:
http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/csprd01/mqtt-v3.1.1-csprd01.html#_Toc376954341
and their Client ID is longer than this library allows.
Thanks and regards,
Jan
May be related to #6?
Running https://gist.github.com/andypiper/5866586 against test.mosquitto.org
the script eventually crashes with:
/A/_info_/Test/PIC32/uart/2/commErrors: { "name" : "uart/2/commErrors" ,"type" : "UINT32" ,"mode" : "R" }
/Global/Units/Unit1: {"tst":"1383862016","lat":"35.397300","_type":"location","lon":"-97.495081","acc":"165m"}
/Global/Units/Unit1/deviceToken: {"tst":"1383851685","dev":"<82087c3c d90f15e9 adf15ecc 8ec85bb6 7e84e890 b09a076d a6bbc304 6a92f429>","_type":"deviceToken"}
/Merckx/STM32F100_UART/__get/system/alive: false
/Merckx/STM32F100_UART/__meta/system/eventCounter: { type : 2, mode : 3 , count total number of events processed}
/Merckx/STM32F100_UART/__meta/system/alive: { type : 8, mode : 1 , }
list-topics.rb:8:in `block (2 levels) in <main>': incompatible character encodings: UTF-8 and ASCII-8BIT (Encoding::CompatibilityError)
from /Users/andyp/gems/gems/mqtt-0.1.0/lib/mqtt/client.rb:242:in `block in get'
from /Users/andyp/gems/gems/mqtt-0.1.0/lib/mqtt/client.rb:240:in `loop'
from /Users/andyp/gems/gems/mqtt-0.1.0/lib/mqtt/client.rb:240:in `get'
from list-topics.rb:7:in `block in <main>'
from /Users/andyp/gems/gems/mqtt-0.1.0/lib/mqtt/client.rb:157:in `connect'
from /Users/andyp/gems/gems/mqtt-0.1.0/lib/mqtt/client.rb:50:in `connect'
from list-topics.rb:6:in `<main>'
MQTT::Client#get
currently has no timeout applied to it. This is very inconvenient in certain situations. From what I see in the code, even network exceptions won't
cause it to unblock.
It's true that Ruby's Queue
implementation is very limited and arguably not a great
example of engineering but libraries such as Bunny still provide
timeout functionality for similar operations (using Timeout
, which surely has it's own
issues).
I'd recommend this client to support optional timeouts, too.
If no client identifier is specified, and hence a random one is generated, always make sure that 'clean session' is set.
This stops lots of anonymous clients that never come back filling up the broker's tables.
https://groups.google.com/group/mqtt/browse_thread/thread/cba7d8d459867eed
I don't think the following example is up to date. It passes an MD5 hash for password.
That did not work for me, while passing the actual password worked fine. Both tests were conducted against RabbitMQ MQTT plugin.
I see that this is licensed under the GPL. Since the GPL doesn't play well with commercial software, could you please relicense it under something friendlier like MIT, BSD or Apache 2? I'd be satisfied with a duel license arrangement.
I'd like to offer this gem as an option for people to use, but I can't as it stands now. I wouldn't want to inadvertently cause people to break laws because they didn't understand how the software was licensed. If it were licensed under something I could use at work, I would also feel encouraged to contribute back.
Right now publishing to an empty topic (by mistake) results in
mqtt/packet.rb:309:in `encode_body': Invalid topic name when serialising packet (RuntimeError)
It clearly should be an ArgumentError
.
Which effectively means, don't send pings.
Less confusing? More like HTTP?
binary = "1!\x00\x13ti/iot/device/40550\x8D\xF8\t@\xC4\xE7O\xF0\xFF0\xE0\xE7"
p binary.length
packet = MQTT::Packet.parse(binary)
p binary.length
Why does the bit size of the :client_id
have to be shorter than 23
?
I'm using the C implementation and that is not limited to 23
bits, I use it on a iOS device and I use the app identifier which is of the form: FBF68BA8-BAFB-41DE-8201-CDD73B7793FF
.
Can that limit be increased?
Hi,
I think the sample in the README.MD should be:
MQTT::Client.connect(endpoint) do |c|
c.publish('test', 'message')
end
Instead of 'topic'.
Taking same options as get() but returning whole packet objects.
Looks like there is no username/password support...planning on adding this? I see a lot of 3.0 clients, but not really useful in a multi-tenant environment...
Detect hung connections.
Check:
hi
please @michaelklishin would can help me.
I have problems with a mqtt client but not happen with amqp client, I use a broker rabbitmq.
my stage are three pc in a network lan
railpc@railpc-VirtualBox:/media/sf_ProjectRubyLinux/Ruby/Semillero$ ruby producer_mqtt.rb
=> Published Message mqtt sended @ 1430402156
/home/railpc/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/mqtt-0.3.1/lib/mqtt/packet.rb:283:in `read_byte': Failed to read byte from socket (MQTT::ProtocolException)
from /home/railpc/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/mqtt-0.3.1/lib/mqtt/packet.rb:31:in `read'
from /home/railpc/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/mqtt-0.3.1/lib/mqtt/client.rb:454:in `receive_packet'
from /home/railpc/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/mqtt-0.3.1/lib/mqtt/client.rb:283:in `block in connect'
require "mqtt"
c = MQTT::Client.connect(
host: '192.168.1.5',
port: 1883,
username: 'guest',
password: 'guest')
loop do
m = "Message mqtt sended @ #{Time.now.to_i} "
c.publish("builds", m)
puts "=> Published #{m}"
sleep 0.2
end
[
{rabbit, [
%%=====================================
%%----Configuration of AMQP protocol----
%% =====================================
{tcp_listeners, [{"192.168.1.5", 5672}]},
{default_user, <<"guest">>},
{default_pass, <<"guest">>},
{default_permissions, [<<".*">>, <<".*">>, <<".*">>]},
{default_vhost, <<"/">>},
{loopback_users, []}
]},
%%-----------------------------------------------------
%%======================================
%%----Configuration Of MQTT protocol----
%%======================================
{rabbitmq_mqtt,[
{vhost,<<"semillero">>},
{default_user, << "guest">>},
{default_pass, <<"guest">>},
{exchange, <<"amp.topic">>},
{tcp_listeners,[{"192.168.1.5", 1883}]},
{allow_anonymous, true}
]}
%%-----------------------------------------------------
].
sorry to my english.
thanks @michaelklishin ๐
I'm thinking about implementing a method to get all topics that the client subscribes to. Use case is as bellow:
Any thought?
I am getting this error when running ruby app.rb please find a solution for it
pi@raspberrypi:~/waterpi-web $ ruby app.rb
/home/pi/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/mqtt-0.3.1/lib/mqtt/client.rb:198:in initialize': No such file or directory @ rb_sysopen - /home/pi/waterpi-web/certs/home/pi/waterpi-web/certs/private.pem.key (Errno::ENOENT) from /home/pi/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/mqtt-0.3.1/lib/mqtt/client.rb:198:inopen'
from /home/pi/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/mqtt-0.3.1/lib/mqtt/client.rb:198:in key_file=' from /home/pi/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/mqtt-0.3.1/lib/mqtt/client.rb:168:inblock in initialize'
from /home/pi/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/mqtt-0.3.1/lib/mqtt/client.rb:167:in each_pair' from /home/pi/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/mqtt-0.3.1/lib/mqtt/client.rb:167:ininitialize'
from /home/pi/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/mqtt-0.3.1/lib/mqtt/client.rb:92:in new' from /home/pi/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/mqtt-0.3.1/lib/mqtt/client.rb:92:inconnect'
from /home/pi/waterpi-web/boot.rb:40:in ' from /home/pi/.rbenv/versions/2.2.3/lib/ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:inrequire'
from /home/pi/.rbenv/versions/2.2.3/lib/ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in require' from app.rb:3:in
'
source code-https://github.com/demirhanaydin/waterpi-web
For security reasons more and more we need to authenticate the topics. Most of the clients (node, arduino) implemented this feauture that has been introduced in the latest MQTT draft. Do you guys have any intention on making this? Thanks.
Here is a challenge that's been troubling me for sometime.
Let's say we have multiple mqtt clients and multiple mqtt backends BUT only one public facing server/port.
We want to identify a user via say their client's SSL Cert or username/password, then proxy all requests for that Client Id (source port/address) to a specific broker based on a lookup table.
Would we be able to configure your tool to support this requirement?
Thank you.
hi @njh
sorry to comment in other issues.
require "mqtt"
c = MQTT::Client.connect(
host: '192.168.1.5',
port: 1883,
username: 'guest',
password: 'guest')
loop do
m = "Message mqtt sended @ #{Time.now.to_i} "
c.publish("builds", m)
puts "=> Published #{m}"
sleep 0.2
end
railpc@railpc-VirtualBox:/media/sf_ProjectRubyLinux/Ruby/Semillero$ ruby producer_mqtt.rb
=> Published Message mqtt sended @ 1430402156
/home/railpc/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/mqtt-0.3.1/lib/mqtt/packet.rb:283:in `read_byte': Failed to read byte from socket (MQTT::ProtocolException)
from /home/railpc/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/mqtt-0.3.1/lib/mqtt/packet.rb:31:in `read'
from /home/railpc/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/mqtt-0.3.1/lib/mqtt/client.rb:454:in `receive_packet'
from /home/railpc/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/mqtt-0.3.1/lib/mqtt/client.rb:283:in `block in connect'
[
{rabbit, [
%%=====================================
%%----Configuration of AMQP protocol----
%% =====================================
{tcp_listeners, [{"192.168.1.5", 5672}]},
{default_user, <<"guest">>},
{default_pass, <<"guest">>},
{default_permissions, [<<".*">>, <<".*">>, <<".*">>]},
{default_vhost, <<"/">>},
{loopback_users, []}
]},
%%-----------------------------------------------------
%%======================================
%%----Configuration Of MQTT protocol----
%%======================================
{rabbitmq_mqtt,[
{vhost,<<"semillero">>},
{default_user, << "guest">>},
{default_pass, <<"guest">>},
{exchange, <<"amp.topic">>},
{tcp_listeners,[{"192.168.1.5", 1883}]},
{allow_anonymous, true}
]}
%%-----------------------------------------------------
].
Thanks @njh .
i'm using this code:
MQTT::Client.connect(:remote_host => 'broker.mqttdashboard.com', :remote_port => 1883) do |client|
client.get_packet('#') do |topic,message|
puts topic
end
end
output:
csquare/cubes/1/temperatureTemp: 22.46
i think
"22.46" is real message.. it mean topic variable printing topic + message .
when i tried to print 'message' variable then it output nothing
what is purpose of "message" variable ?
I keep getting the following issue when I try to run the example code:
/Users/rolandjitsu/Projects/Pulsr/Client/vendor/bundle/gems/mqtt-0.2.0/lib/mqtt/packet.rb:271:in `read_byte': Failed to read byte from socket (MQTT::ProtocolException)
from /Users/rolandjitsu/Projects/Pulsr/Client/vendor/bundle/gems/mqtt-0.2.0/lib/mqtt/packet.rb:32:in `read'
from /Users/rolandjitsu/Projects/Pulsr/Client/vendor/bundle/gems/mqtt-0.2.0/lib/mqtt/client.rb:440:in `receive_packet'
from /Users/rolandjitsu/Projects/Pulsr/Client/vendor/bundle/gems/mqtt-0.2.0/lib/mqtt/client.rb:272:in `block in connect'
I can successfully subscribe and publish with the MQTTKit Objective-C implementation of the mosquito lib. But when I run the ruby code, I can see on my device that it's actually trying to publish something (instead of subscribing) and it fails afterwards.
All I am doing is:
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __FILE__)
ENV['RACK_ENV'] ||= 'development'
require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
Bundler.require :default, ENV['RACK_ENV'].to_sym
# Subscribe example
MQTT::Client.connect(:remote_host => 'iot.eclipse.org', :client_id => 'FBF68BA8') do |client|
client.get('/pulsr') do |topic, message|
puts "#{topic}: #{message}"
end
end
Hi! Could you bump the version and push to rubygems? I rely on the last_ping_response time to ensure connection status. Thanks in advance :)
When Client#unsubscribe
argument is passed as an array, the server will get
"[\"c/topic\"]"]
which is incorrect. This client should coerce provided values to an array better.
Registration:
http://www.dns-sd.org/ServiceTypes.html
Discussion:
https://groups.google.com/d/msg/mqtt/hixhyVMZVxg/T6k3p4BP-GAJ
Python implementation:
https://github.com/jpmens/paho-mqtt-dns-srv/commit/10c2ad7a224ba02f15133854187bd0a789c049bb
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.