Skip to content

fayer1986/emq-lua-hook

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

emq-lua-hook

This plugin make it possible to write hooks in lua scripts.

Lua virtual machine is implemented by luerl which supports Lua 5.2. Following features may not work properly:

  • label and goto
  • tail-call optimisation in return
  • only limited standard libraries
  • proper handling of __metatable

For the supported functions, please refer to luerl's project page.

Lua scripts are stored in hook_lua directory, and will be loaded automatically. If a script is changed during runtime, it should be reloaded to take effect.

Each lua script could export several functions binding with emqttd hooks, triggered by message publish, topic subscribe, client connect, etc. Different lua scripts may export same type function, binding with a same event. But their order being triggered is not guaranteed.

To start this plugin, run following command:

bin/emqttd_ctl plugins load emq_lua_hook

NOTE

  • Since lua VM is run on erlang VM, its performance is poor. Please do NOT write long or complicated lua scripts which may degrade entire system.
  • It's hard to debug lua script in emqttd environment. Recommended to unit test your lua script in your host first. If everything is OK, deploy it to empttd hook_lua directory.
  • Global variable will lost its value for each call. Do NOT use global variable in lua scripts.

Hook API

on_message_publish

function on_message_publish(topic, payload, qos, retain)
    -- do your job here 
    if some_condition then
        return new_topic, new_payload, new_qos, new_retain
    else
        return false
    end
end

This API is called before publishing message into mqtt engine. It's possible to change message or cancel publish in this API.

Input

  • topic : a string, mqtt message's topic
  • payload : a string, mqtt message's payload
  • qos : a number, mqtt message's QOS (0, 1, 2)
  • retain : a boolean, mqtt message's retain flag

Output

  • new_topic : a string, change mqtt message's topic
  • new_payload : a string, change mqtt message's payload
  • new_qos : a number, change mqtt message's QOS
  • new_retain : a boolean, change mqtt message's retain flag
  • false : cancel publishing this mqtt message

on_message_delivered

function on_message_delivered(ClientId, Username, topic, payload, qos, retain)
    -- do your job here 
    return 0

This API is called after a message has been pushed to mqtt clients.

Input

  • ClientId : a string, mqtt client id.
  • Username : a string mqtt username
  • topic : a string, mqtt message's topic
  • payload : a string, mqtt message's payload
  • qos : a number, mqtt message's QOS (0, 1, 2)
  • retain : a boolean, mqtt message's retain flag

Output

  • always be 0

on_message_acked

function on_message_acked(ClientId, Username, Topic, Payload, Qos, Retain)
    return 0
end"

This API is called after a message has been acknowledged.

Input

  • ClientId : a string, mqtt client id.
  • Username : a string mqtt username
  • topic : a string, mqtt message's topic
  • payload : a string, mqtt message's payload
  • qos : a number, mqtt message's QOS (0, 1, 2)
  • retain : a boolean, mqtt message's retain flag

Output

  • always be 0

on_client_connected

function on_client_connected(ClientId, UserName, ReturnCode)
    return 0
nend

This API is called after a mqtt client has establish a connection with broker.

Input

  • ClientId : a string, mqtt client id.
  • Username : a string mqtt username
  • ReturnCode : a number, has following values
    • 0 : Connection accepted
    • 1 : Unacceptable protocol version
    • 2 : Client Identifier is correct UTF-8 but not allowed by the Server
    • 3 : Server unavailable
    • 4 : Username or password is malformed
    • 5 : Client is not authorized to connect

Output

  • always be 0

on_client_subscribe

function on_client_subscribe(ClientId, Username, Topic)
    -- do your job here
    if some_condition then
        return new_topic
    else
        return false
    end
end

This API is called before mqtt engine process client's subscribe command. It is possible to change topic or cancel it.

Input

  • ClientId : a string, mqtt client id.
  • Username : a string mqtt username
  • Topic : a string, mqtt message's topic

Output

  • new_topic : a string, change mqtt message's topic
  • false : cancel subscription

on_client_unsubscribe

 function on_client_unsubscribe(ClientId, Username, Topic)
    -- do your job here
    if some_condition then
        return new_topic
    else
        return false
    end
end

This API is called before mqtt engine process client's unsubscribe command. It is possible to change topic or cancel it.

Input

  • ClientId : a string, mqtt client id.
  • Username : a string mqtt username
  • Topic : a string, mqtt message's topic

Output

  • new_topic : a string, change mqtt message's topic
  • false : cancel unsubscription

on_client_disconnected

function on_client_disconnected(ClientId, Username, Error)
    return 0
end

This API is called after a mqtt client has disconnected.

Input

  • ClientId : a string, mqtt client id.
  • Username : a string mqtt username
  • Error : a string, denote the disconnection reason.

Output

  • always be 0.

on_session_subscribed

function on_session_subscribed(ClientId, Username, Topic)
    return 0
end

This API is called after a subscription has been done.

Input

  • ClientId : a string, mqtt client id.
  • Username : a string mqtt username
  • Topic : a string, mqtt's topic filter.

Output

  • always be 0.

on_session_unsubscribed

function on_session_unsubscribed(ClientId, Username, Topic)
    return 0
end

This API is called after a unsubscription has been done.

Input

  • ClientId : a string, mqtt client id.
  • Username : a string mqtt username
  • Topic : a string, mqtt's topic filter.

Output

  • always be 0.

register_hook

function register_hook()
    return "hook_name"
end

function register_hook()
    return "hook_name1", "hook_name2", ... , "hook_nameX"
end

This API exports hook(s) implemented in its lua script.

Output

  • hook_name must be a string, which is equal to the hook API(s) implemented. Possible values:
  • "on_message_publish"
  • "on_message_delivered"
  • "on_message_acked"
  • "on_client_connected"
  • "on_client_subscribe"
  • "on_client_unsubscribe"
  • "on_client_disconnected"
  • "on_session_subscribed"
  • "on_session_unsubscribed"

example code

function on_message_publish(topic, payload, qos, retain)
    return topic, "hello", qos, retain
end

function register_hook()
    return "on_message_publish"
end

Save this script as example.lua in hook_lua directory. emq-lua-hook will load it automatically during bootstrap.

management command

load

emqttd_ctl luahook load script_name

This command will load lua file "script_name.lua" in hook_lua directory, into emqttd hook.

unload

emqttd_ctl luahook unload script_name

This command will unload lua file "script_name.lua" out of emqttd hook.

reload

emqttd_ctl luahook reload script_name

This command will reload lua file "script_name.lua" in hook_lua. It is useful if a lua script has been modified and apply it immediately.

enable

emqttd_ctl luahook enable script_name

This command will rename lua file "script_name.lua.x" to "script_name.lua", and load it immediately.

disable

emqttd_ctl luahook disable script_name

This command will unload this script, and rename lua file "script_name.lua" to "script_name.lua.x", which will not be loaded during next boot.

License

Apache License Version 2.0

Author

Feng Lee [email protected]

About

EMQ Lua Hook

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Erlang 98.9%
  • Makefile 1.1%