GithubHelp home page GithubHelp logo

flukso / lua-mosquitto Goto Github PK

View Code? Open in Web Editor NEW
63.0 17.0 42.0 66 KB

Lua bindings to the libmosquitto MQTT client library.

Home Page: https://github.com/flukso/lua-mosquitto

License: Other

C 71.99% Makefile 2.25% Lua 25.76%
lua mosquitto mqtt mqtt-client lua-bindings libmosquitto

lua-mosquitto's Introduction

lua-mosquitto

Lua bindings to the libmosquitto client library.

The parameters to all functions are as per libmosquitto's api only with sensible defaults for optional values, and return values directly rather than via pointers.

Generated API documentation for the lua functions is also available (Direct link if you are within github)

Compile

You need Lua and mosquitto development packages (headers and libs) to build lua-mosquitto.

Compile with

make

You can override the pkg-config package name to set a specific Lua version. For example:

make LUAPKG=lua5.2

Example usage

Here is a very simple example that subscribes to the broker $SYS topic tree and prints out the resulting messages:

mqtt = require("mosquitto")
client = mqtt.new()

client.ON_CONNECT = function()
        print("connected")
        client:subscribe("$SYS/#")
        local mid = client:subscribe("complicated/topic", 2)
end

client.ON_MESSAGE = function(mid, topic, payload)
        print(topic, payload)
end

broker = arg[1] -- defaults to "localhost" if arg not set
client:connect(broker)
client:loop_forever()

Here is another simple example that will just publish a single message, "hello", to the topic "world" and then disconnect.

mqtt = require("mosquitto")
client = mqtt.new()

client.ON_CONNECT = function()
        client:publish("world", "hello")
        local qos = 1
        local retain = true
        local mid = client:publish("my/topic/", "my payload", qos, retain)
end

client.ON_PUBLISH = function()
	client:disconnect()
end

broker = arg[1] -- defaults to "localhost" if arg not set
client:connect(broker)
client:loop_forever()

lua-mosquitto's People

Contributors

icarus75 avatar israellot avatar karlp avatar mastervitronic avatar ncopa avatar nemik avatar pejackson avatar pkisztelinski avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

lua-mosquitto's Issues

Segmentation fault(core dumped) when using mosquitto client as a thread along with lua lanes

Hi,

I am using lua lanes to run os threads to collect data and have an mqtt client running as one of the thread. After some time or sometimes immediately after connecting with broker, my entire software crashes with segmentation fault error and Ubuntu 16.04 error reporting shows up. I tried running it on openwrt platform too and faced similar issues. I changed mosquitto client library to paho and now its stable. I am wondering if there is some issue which you are aware of. I can share the traceback if interested.

Thanks,
Aditya

cpu hog on teardown? pthread_join

I'm seeing this in an app I have, and I haven't got a lot of debugging yet, it seems to happen after I'm running for a while, but the CPU usage of the app shoots up, and it's no longer "running" but it hasn't exited. I finally hooked gdb up to it today while it was in this state, and it seems like it's stuck trying to tear down?

I've never seen this with a libmosquitto C app, so even though the stack ends in mosquitto, I kinda feel it's an issue in the lua-mosquitto binding?

Source application is at: https://github.com/remakeelectric/owrt_pub_feeds/blob/output-sparkfun/output-sparkfun/files/usr/bin/output-sparkfun

karlp@teros:~/src/smartgate_firmware/openwrt-bb (rme)$ ./scripts/remote-gdb 192.168.1.34:9999 build_dir/target-mips_mips32_uClibc-0.9.33.2/lua-5.1.5/src/lua
Using target mips_mips32 (uClibc-0.9.33.2)
Python Exception <type 'exceptions.ImportError'> No module named gdb: 

warning: 
Could not load the Python gdb module from `/home/karlp/src/smartgate_firmware/openwrt-bb/staging_dir/toolchain-mips_mips32_gcc-4.8-linaro_uClibc-0.9.33.2/share/gdb/python'.
Limited Python support is available from the _gdb module.
Suggest passing --data-directory=/path/to/gdb/data-directory.

GNU gdb (Linaro GDB) 7.6-2013.05
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=x86_64-redhat-linux --target=mips-openwrt-linux-uclibc".
For bug reporting instructions, please see:
<http://bugs.launchpad.net/gdb-linaro/>...
Reading symbols from /home/karlp/src/smartgate_firmware/openwrt-bb/build_dir/target-mips_mips32_uClibc-0.9.33.2/lua-5.1.5/src/lua...done.
0x76f301e0 in pthread_join (threadid=1994786096, thread_return=0x0)
    at libpthread/nptl/pthread_join.c:89
89      lll_wait_tid (pd->tid);
(gdb) bt
#0  0x76f301e0 in pthread_join (threadid=1994786096, thread_return=0x0)
    at libpthread/nptl/pthread_join.c:89
#1  0x77110978 in _mosquitto_destroy ()
   from /home/karlp/src/smartgate_firmware/openwrt-bb/scripts/../staging_dir/target-mips_mips32_uClibc-0.9.33.2/root-atheros/usr/lib/libmosquitto.so.1
#2  0x77110ff8 in mosquitto_destroy ()
   from /home/karlp/src/smartgate_firmware/openwrt-bb/scripts/../staging_dir/target-mips_mips32_uClibc-0.9.33.2/root-atheros/usr/lib/libmosquitto.so.1
#3  0x7712da1c in ctx_destroy ()
   from /home/karlp/src/smartgate_firmware/openwrt-bb/scripts/../staging_dir/target-mips_mips32_uClibc-0.9.33.2/root-atheros/usr/lib/lua/mosquitto.so
#4  0x7722e9a8 in luaD_precall ()
   from /home/karlp/src/smartgate_firmware/openwrt-bb/scripts/../staging_dir/target-mips_mips32_uClibc-0.9.33.2/root-atheros/usr/lib/liblua.so.5.1.5
#5  0x7722eb60 in luaD_call ()
   from /home/karlp/src/smartgate_firmware/openwrt-bb/scripts/../staging_dir/target-mips_mips32_uClibc-0.9.33.2/root-atheros/usr/lib/liblua.so.5.1.5
#6  0x7722fe24 in GCTM ()
   from /home/karlp/src/smartgate_firmware/openwrt-bb/scripts/../staging_dir/target-mips_mips32_uClibc-0.9.33.2/root-atheros/usr/lib/liblua.so.5.1.5
#7  0x77230fa8 in singlestep ()
   from /home/karlp/src/smartgate_firmware/openwrt-bb/scripts/../staging_dir/target-mips_mips32_uClibc-0.9.33.2/root-atheros/usr/lib/liblua.so.5.1.5
#8  0x77231290 in luaC_fullgc ()
   from /home/karlp/src/smartgate_firmware/openwrt-bb/scripts/../staging_dir/target-mips_mips32_uClibc-0.9.33.2/root-atheros/usr/lib/liblua.so.5.1.5
#9  0x772299cc in lua_gc ()
   from /home/karlp/src/smartgate_firmware/openwrt-bb/scripts/../staging_dir/target-mips_mips32_uClibc-0.9.33.2/root-atheros/usr/lib/liblua.so.5.1.5
#10 0x00401168 in docall ()
   from /home/karlp/src/smartgate_firmware/openwrt-bb/scripts/../staging_dir/target-mips_mips32_uClibc-0.9.33.2/root-atheros/usr/bin/lua
#11 0x00401cc8 in pmain ()
   from /home/karlp/src/smartgate_firmware/openwrt-bb/scripts/../staging_dir/target-mips_mips32_uClibc-0.9.33.2/root-atheros/usr/bin/lua
#12 0x7722e9a8 in luaD_precall ()
   from /home/karlp/src/smartgate_firmware/openwrt-bb/scripts/../staging_dir/target-mips_mips32_uClibc-0.9.33.2/root-atheros/usr/lib/liblua.so.5.1.5
#13 0x7722eb60 in luaD_call ()
   from /home/karlp/src/smartgate_firmware/openwrt-bb/scripts/../staging_dir/target-mips_mips32_uClibc-0.9.33.2/root-atheros/usr/lib/liblua.so.5.1.5
#14 0x7722dc44 in luaD_rawrunprotected ()
   from /home/karlp/src/smartgate_firmware/openwrt-bb/scripts/../staging_dir/target-mips_mips32_uClibc-0.9.33.2/root-atheros/usr/lib/liblua.so.5.1.5
#15 0x7722edc4 in luaD_pcall ()
   from /home/karlp/src/smartgate_firmware/openwrt-bb/scripts/../staging_dir/target-mips_mips32_uClibc-0.9.33.2/root-atheros/usr/lib/liblua.so.5.1.5
#16 0x77229850 in lua_cpcall ()
   from /home/karlp/src/smartgate_firmware/openwrt-bb/scripts/../staging_dir/target-mips_mips32_uClibc-0.9.33.2/root-atheros/usr/lib/liblua.so.5.1.5
#17 0x00400bc0 in main ()
   from /home/karlp/src/smartgate_firmware/openwrt-bb/scripts/../staging_dir/target-mips_mips32_uClibc-0.9.33.2/root-atheros/usr/bin/lua
(gdb) 

Lua 5.2 support

It fails to build with Lua 5.2:

dev32-edge:~/src/lua-mosquitto$ make INCDIR=$(pkg-config --cflags lua5.2)
cc -c -fPIC -std=gnu99 -Wall -pedantic -I/usr/include/lua5.2 -o lua-mosquitto.o lua-mosquitto.c
lua-mosquitto.c: In function 'luaopen_mosquitto':
lua-mosquitto.c:710:17: error: 'LUA_ENVIRONINDEX' undeclared (first use in this function)
  lua_replace(L, LUA_ENVIRONINDEX);
                 ^
lua-mosquitto.c:710:17: note: each undeclared identifier is reported only once for each function it appears in
lua-mosquitto.c:716:2: warning: implicit declaration of function 'luaL_register' [-Wimplicit-function-declaration]
  luaL_register(L, NULL, ctx_M);
  ^
makefile:26: recipe for target 'lua-mosquitto.o' failed
make: *** [lua-mosquitto.o] Error 1

Callbacks are called from other threads

When in async mode, callbacks seem to be called when mosquitto feels like it, which is entirely undefined behaviour.

local mqtt = require "mosquitto"
local gettid do
	local ffi = require "ffi" -- use luajit or https://github.com/facebookarchive/luaffifb
	ffi.cdef[[int syscall(int);]]
	gettid = function()
		return ffi.C.syscall(186)
	end
end
local client = mqtt.new()
client:callback_set("ON_CONNECT", function()
	print("connected", gettid())
	client:subscribe("$SYS/#")
end)
client:callback_set("ON_MESSAGE", function(mid, topic, payload)
	print("message", gettid(), mid, topic, payload)
end)
local broker = arg[1] or "localhost"
assert(client:connect_async(broker))
assert(client:loop_start())

client:loop_read()
client:loop_read()
client:loop_write()
client:loop_misc()
client:loop_read()
client:loop_read()
client:loop_write()
client:loop_misc()
client:loop_read()
client:loop_read()
client:loop_write()

Create new version tag v0.2

Do you think it would be possible to create new tag with version v0.2 that has TLS support in it so it can be easily updated in openwrt repository?
Thanks

Callbacks need to be longjmp safe

Callback functions (on_connect, on_message, etc.) are called from non-lua code; which I cannot see as documented to be longjmp safe.

Lua C api functions will longjmp out on failure to the last pcall.
To fix, your lua function invocations should use lua_pcall.

Additionally, other functions such as lua_pushstring can longjmp out on memory allocation failure.

lua_pushstring(ctx->L, str);

These should also be called from inside a pcall (push a pointer on the stack instead and then inside the pcall use lua_pushstring).

loop() throws "A network protocol error occurred when communicating with the broker" on disconnect

Until I have a valid connection, and then whilst I have a valid connection, loop(0) works fine. However if the connection drops, loop() calls the ON_DISCONNECT handler but then throws an exception.

I can catch the error with pcall but this doesn't seem like intended behaviour and I don't know if there is any cleaning up that needs doing after the exception prior to a reconnect?

Sample code:

MQTT_HOST  = '<HOST>'
MQTT_PORT  = <PORT>

MQTT_USER  = <USER>
MQTT_PASS  = <PASS>

MQTT_PEM = "/tmp/broker-cert.pem"

local mq = mqtt.new()
local mq_status = 'disconnected'

-- Setup MQTT connection
if MQTT_PEM then 
        mq:tls_set(MQTT_PEM) 
        mq:tls_insecure_set(true)
end
if MQTT_USER then mq:login_set(MQTT_USER,MQTT_PASS) end

mq.ON_CONNECT = function()
    mq_status = 'connected'
    print('Connected')
end

mq.ON_DISCONNECT = function(was_clean, rc, str)
    mq_status = 'disconnected'
    print("Disconnection detected")
end

mq.ON_MESSAGE = function(mid, k, v)
        print(k + '=' + v)
end

-- MAIN LOOP
while true do
        socket.sleep(0.1)
        -- Attempt MQTT connection if nec
        if mq_status == 'disconnected' then
                mq_status = 'connecting'
                ok, e, err = mq:connect(MQTT_HOST, MQTT_PORT)
                if ok then
                        print('Connecting')
                else
                        print('Unable to connect')
                        mq_status = 'disconnected'
                end
        end

    -- Handle MQTT comms
       ok, errno, errstr = mq:loop(0)
end

Platform: Teltonika TRB unit running OpenWRT, lib-mosquitto 0.4.1-1 package

mqtt5 support API design?

None of the mqttv5 support functions are implemented yet. I'm considering what the APIs shoudl look like?

I believe ~all of the _v5 functions should just be automatically called IFF properties are present as the final argument? Does this make it too hard to use the "sensible defaults" for all the other parameters?

ala:

-- old
publish (topic, payload[, qos=0[, retain=nil]])
--new
publish (topic, payload[, qos=0[, retain=nil[, properties=nil]]])
if properties are present, the _v5 function is called after constructing a properties set.

I believe the properties should just be handled as lua arrays, no need to expose all the internals here.
ala:

local props = {
   {m.PROP_RESPONSE_TOPIC, "some string"},
   {m.PROP_BLAH, 9999},
   {m.PROP_ETC, foo}
}
publish(topic, payload, 0, nil, props)

The lua lib can correctly create a proplist by type inspection.

I do NOT know how to best handle the callback registration. We can't always call _v5, as v5 might not be available. Do we have to store the v5 state from connect time or init time and then always use _v5 "as appropriate" ?

Usage of luaL_checkint

I was wondering why the deprecated luaL_checkint is being used instead of luaL_checkinteger. I see that it also made the fix in #30 necessary. Could we not just replace it with luaL_checkinteger which is already being in the code?

Cheers,
Bhargava Srinarasi

create release tag

Hi,

I woudl like to package lua-mosquitto with Alpine Linux, but i don't want give support for anything that does not has a proper release.

I have also some other improvements too in my lua-mosquitto fork:

It would be nice if you could consider cherry-pick some of those and then create a release tag.

Thanks!

SEO; add mqtt to description

I've been fiddling with mqtt for a week now, and only now found this library. I'd like to suggest editing the project descriptions and tags (on Lua Rocks and Github) to include both "Lua" and "mqtt" as well, besides only "mosquitto".

valgrind leak

I can't work it out, but simply opening and closing the mosquitto libs causes valgrind errors.

C code, no leaks in valgrind.

int main(int argc, char** argv) {
        mosquitto_lib_init();
        printf("ok, done, now exiting\n");
        mosquitto_lib_cleanup();
        return 0;
}

Lua code, leaks 1 32byte block in valgrind

#!/usr/bin/lua
local mosq = require("mosquitto")
mosq.init()
print("Exiting thanks")
mosq.cleanup()

Valgrind report...

==5387== 64 (32 direct, 32 indirect) bytes in 1 blocks are definitely lost in loss record 5 of 8
==5387==    at 0x4A06409: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==5387==    by 0x32EAC68E62: ???
==5387==    by 0x32EACDF71E: ???
==5387==    by 0x3F072477F9: ???
==5387==    by 0x3F07249768: ???
==5387==    by 0x3F0724F028: ???
==5387==    by 0x3F01A06414: ???
==5387==    by 0x3F01A037D2: ???
==5387==    by 0x5017C4A: ???
==5387==    by 0x32FB40C027: ??? (in /usr/lib64/liblua-5.1.so)
==5387==    by 0x32FB41674E: ??? (in /usr/lib64/liblua-5.1.so)
==5387==    by 0x32FB40C43C: ??? (in /usr/lib64/liblua-5.1.so)
==5387== 
==5387== LEAK SUMMARY:
==5387==    definitely lost: 32 bytes in 1 blocks
==5387==    indirectly lost: 32 bytes in 1 blocks
==5387==      possibly lost: 0 bytes in 0 blocks
==5387==    still reachable: 3,541 bytes in 11 blocks
==5387==         suppressed: 0 bytes in 0 blocks

Any ideas? I know it's not going to ever really matter, but it's nice to make them all disappear.

reconnect_async missing

All, the connect_async works well, but there is no reconnect_async in these bindings, so once you lose the connection you will need to close and restart everything .. could that be added ?

Callbacks occur in same coroutine that mqtt.new is called from

This causes issues for a few reasons.
e.g. Coroutines can die:

local mqtt = require("mosquitto")
print("Main thread:", coroutine.running())
local client
do
	local co = coroutine.create(function()
		print("Calling mqtt.new from:", coroutine.running())
		client = mqtt.new()
		error() -- coroutine will now be dead.
	end)
	coroutine.resume(co)
	print("THE STATUS OF ", co, "IS NOW: ", coroutine.status(co))
end
client:callback_set("ON_CONNECT", function()
	print("On Connect called from:", coroutine.running())
	client:subscribe("$SYS/#")
end)
client:callback_set("ON_MESSAGE", function(mid, topic, payload)
	print("On Message called from:", coroutine.running())
	print(topic, payload)
end)

client:connect()
client:loop_forever()

rockspec for Lua 5.3: LUA_COMPAT_APIINTCASTS

Attempting to install on Lua 5.3 results in a compilation error because of the deprecated luaL_checkint. Should the rockspec define LUA_COMPAT_APIINTCASTS so that the compatibility macro is available?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.