diff --git a/docs/source/changes.rst b/docs/source/changes.rst index 9d4436c57..ce5bd6191 100644 --- a/docs/source/changes.rst +++ b/docs/source/changes.rst @@ -11,11 +11,119 @@ Changes Version 2.0 (West of West Lake) ------------------------------- -*Release Date: 2016-08-29* +*Release Date: 2016-08-30* -Improve the design of PubSub and Router: +*Release Name: West of West Lake* -.. images:: _static/images/publish.png +.. NOTE:: Dont' upgrade 1.x production deployment to 2.0-beta1 release. + +EMQ - Shortened Project Name +---------------------------- + +Adopt a shortened projectname: EMQ(Erlang/Enterprise/Elastic MQTT Broker),E means Erlang/OTP, Enterprise and Elastic. + +Improve the Release Management +------------------------------ + +In order to iterate the project fast, we will adopt a new release management strategy since 2.0. There will be two or three 'Preview Release' named beta1, beta2 or beta3, and then one or two 'Release Candidate' named rc1, rc2 before a Major version is production ready. + +Seperate Rel from Application +----------------------------- + +We split the emqttd 1.x project into two projects since 2.0-beta1 release to resolve the plugins' dependency issue. + +A new project named `emqttd-relx`_ is created and responsible for buiding the emqttd application and the plugins:: + + git clone https://github.com/emqtt/emqttd-relx.git + + cd emqttd-relx && make + + cd _rel/emqttd && ./bin/emqttd console + +erlang.mk and relx +------------------ + +The rebar which is used in 1.x release is replaced by `erlang.mk`_ and `relx`_ tools since 2.0-beta1 release. + +You can check the 'Makefile' and 'relx.config' in the release project of the borker: `emqttd-relx`_ . + +Improve Git Branches Management +------------------------------- + ++------------+-------------------------------------------+ +| stable | 1.x Stable Branch | ++------------+-------------------------------------------+ +| master | 2.x Master Branch | ++------------+-------------------------------------------+ +| emq10 | 1.x Developement Branch | ++------------+-------------------------------------------+ +| emq20 | 2.x Development Branch | ++------------+-------------------------------------------+ +| emq30 | 3.x Development Branch | ++------------+-------------------------------------------+ +| issue#{id} | BugFix Branch | ++------------+-------------------------------------------+ + +New Config Syntax +----------------- + +Since 2.0-beta1 release the configuration file of the broker and plugins adopt a new syntax like rebar.config or relx.config: + +etc/emqttd.conf for example:: + + %% Max ClientId Length Allowed. + {mqtt_max_clientid_len, 512}. + + %% Max Packet Size Allowed, 64K by default. + {mqtt_max_packet_size, 65536}. + + %% Client Idle Timeout. + {mqtt_client_idle_timeout, 30}. % Second + +MQTT-SN Protocol Plugin +----------------------- + +The MQTT-SN Protocol Plugin `emqttd_sn`_ has been ready in 2.0-beta1 release. The default UDP port of MQTT-SN is 1884. + +Load the plugin:: + + ./bin/emqttd_ctl plugins load emqttd_sn + +Improve Design of PubSub and Router +----------------------------------- + +.. image:: _static/images/publish.png + +Improve Plugin Management +------------------------- + +The plugin of EMQ 2.0 broker is a normal erlang application which depends on and extends 'emqttd'. User can create a standalone plugin application project, and add it to `emqttd-relx`_ Makefiel as a dependency. + +All the plugins' config files will be copied to emqttd/etc/plugins/ folder when making emqttd brinary packages in `emqttd-relx`_ project:: + + ▾ emqttd/ + ▾ etc/ + ▸ modules/ + ▾ plugins/ + emqtt_coap.conf + emqttd.conf + emqttd_auth_http.conf + emqttd_auth_mongo.conf + emqttd_auth_mysql.conf + emqttd_auth_pgsql.conf + emqttd_auth_redis.conf + emqttd_coap.conf + emqttd_dashboard.conf + emqttd_plugin_template.conf + emqttd_recon.conf + emqttd_reloader.conf + emqttd_sn.conf + emqttd_stomp.conf + +EMQ 2.0 Documentation +--------------------- + +http://emqtt.io/docs/v2/index.html or http://docs.emqtt.com/emq20/ .. _release_1.1.3: diff --git a/docs/source/cluster.rst b/docs/source/cluster.rst index 8ebd992ba..96ef37070 100644 --- a/docs/source/cluster.rst +++ b/docs/source/cluster.rst @@ -245,7 +245,7 @@ The Firewall If there is a firewall between clustered nodes, the cluster requires to open 4369 port used by epmd daemon, and a port segment for nodes' communication. -Configure the port segment in etc/emqttd.config, for example: +Configure the port segment in releases/2.0/sys.config, for example: .. code-block:: erlang diff --git a/docs/source/commands.rst b/docs/source/commands.rst index 7b4243c96..c4e8645c5 100644 --- a/docs/source/commands.rst +++ b/docs/source/commands.rst @@ -20,7 +20,7 @@ Show running status of the broker:: $ ./bin/emqttd_ctl status Node 'emqttd@127.0.0.1' is started - emqttd 1.1 is running + emqttd 2.0 is running .. _command_broker:: @@ -382,10 +382,6 @@ Query the subscription table of the broker: +--------------------------------------------+--------------------------------------+ | subscriptions show | Show a subscription | +--------------------------------------------+--------------------------------------+ -| subscriptions add | Add a static subscription manually | -+--------------------------------------------+--------------------------------------+ -| subscriptions del | Remove a static subscription manually| -+--------------------------------------------+--------------------------------------+ subscriptions list ------------------ @@ -415,22 +411,6 @@ Show the subscriptions of a MQTT client:: clientid: [{<<"x">>,1},{<<"topic2">>,1},{<<"topic3">>,1}] -subscriptions add ------------------------------------------- - -Add a static subscription manually:: - - $ ./bin/emqttd_ctl subscriptions add clientid new_topic 1 - ok - -subscriptions del ------------------------------------- - -Remove a static subscription manually:: - - $ ./bin/emqttd_ctl subscriptions del clientid new_topic - ok - .. _command_plugins:: ------- diff --git a/docs/source/conf.py b/docs/source/conf.py index f96ed0579..3fafdfd06 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -48,7 +48,7 @@ source_suffix = '.rst' master_doc = 'index' # General information about the project. -project = u'Erlang MQTT Broker' +project = u'EMQ 2.0 - Erlang MQTT Broker' copyright = u'2016, Feng Lee' # The version info for the project you're documenting, acts as replacement for @@ -56,9 +56,9 @@ copyright = u'2016, Feng Lee' # built documents. # # The short X.Y version. -version = '1.0' +version = '2.0' # The full version, including alpha/beta/rc tags. -release = '1.0' +release = '2.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/docs/source/config.rst b/docs/source/config.rst index 7ddab18d9..f109a246b 100644 --- a/docs/source/config.rst +++ b/docs/source/config.rst @@ -5,24 +5,66 @@ Configuration ============= -Configuration files of the broker are under 'etc/' folder, including: +The two main configuration files of the broker are under 'etc/' folder: +-------------------+-----------------------------------+ | File | Description | +-------------------+-----------------------------------+ | etc/vm.args | Erlang VM Arguments | +-------------------+-----------------------------------+ -| etc/emqttd.config | emqttd broker Config | -+-------------------+-----------------------------------+ -| etc/acl.config | ACL Config | -+-------------------+-----------------------------------+ -| etc/clients.config| ClientId Authentication | -+-------------------+-----------------------------------+ -| etc/rewrite.config| Rewrite Rules | -+-------------------+-----------------------------------+ -| etc/ssl/* | SSL certificate and key files | +| etc/emqttd.conf | emqttd broker Config | +-------------------+-----------------------------------+ +---------------------------- +Plugins' Configuration Files +---------------------------- + ++----------------------------------------+-----------------------------------+ +| File | Description | ++----------------------------------------+-----------------------------------+ +| etc/plugins/emqttd_auth_http.conf | HTTP Auth/ACL Plugin Config | ++----------------------------------------+-----------------------------------+ +| etc/plugins/emqttd_auth_mongo.conf | MongoDB Auth/ACL Plugin Config | ++----------------------------------------+-----------------------------------+ +| etc/plugins/emqttd_auth_mysql.conf | MySQL Auth/ACL Plugin Config | ++----------------------------------------+-----------------------------------+ +| etc/plugins/emqttd_auth_pgsql.conf | Postgre Auth/ACL Plugin Config | ++----------------------------------------+-----------------------------------+ +| etc/plugins/emqttd_auth_redis.conf | Redis Auth/ACL Plugin Config | ++----------------------------------------+-----------------------------------+ +| etc/plugins/emqttd_coap.conf | CoAP Protocol Plugin Config | ++----------------------------------------+-----------------------------------+ +| etc/plugins/emqttd_dashboard.conf | Dashboard Plugin Config | ++----------------------------------------+-----------------------------------+ +| etc/plugins/emqttd_plugin_template.conf| Template Plugin Config | ++----------------------------------------+-----------------------------------+ +| etc/plugins/emqttd_recon.conf | Recon Plugin Config | ++----------------------------------------+-----------------------------------+ +| etc/plugins/emqttd_reloader.conf | Reloader Plugin Config | ++----------------------------------------+-----------------------------------+ +| etc/plugins/emqttd_sn.conf | MQTT-SN Protocal Plugin Config | ++----------------------------------------+-----------------------------------+ +| etc/plugins/emqttd_stomp.conf | Stomp Protocl Plugin Config | ++----------------------------------------+-----------------------------------+ + +---------------------------- +Modules' Configuration Files +---------------------------- + +The modules' configuration files are in etc/modules/ folder, and referrenced by etc/emqttd.conf: + ++----------------------------+-----------------------------------+ +| File | Description | ++----------------------------+-----------------------------------+ +| etc/modules/acl.config | Internal ACL Rules | ++----------------------------+-----------------------------------+ +| etc/modules/client.config | Config for ClientId Auth Module | ++----------------------------+-----------------------------------+ +| etc/modules/rewrite.config | Config for Rewrite Module | ++----------------------------+-----------------------------------+ +| etc/ssl/* | SSL Certfile and Keyfile | ++-----------------------------+----------------------------------+ + ----------- etc/vm.args ----------- @@ -102,44 +144,11 @@ The name and cookie of Erlang Node should be configured when clustering:: ## Cookie for distributed erlang -setcookie emqttdsecretcookie ------------------ -etc/emqttd.config ------------------ - -This is the main emqttd broker configuration file. - -File Syntax ------------ - -The file use the standard Erlang config syntax and consists of a list of erlang applications and their environments. - -.. code-block:: erlang - - [{kernel, [ - {start_timer, true}, - {start_pg2, true} - ]}, - {sasl, [ - {sasl_error_logger, {file, "log/emqttd_sasl.log"}} - ]}, - - ... - - {emqttd, [ - ... - ]} - ]. - -The file adopts Erlang Term Syntax: - -1. [ ]: List, seperated by comma -2. { }: Tuple, Usually {Env, Value} -3. % : comment - +------------------ Log Level and File ------------------ -Logger of emqttd broker is implemented by 'lager' application: +Logger of emqttd broker is implemented by 'lager' application, which is configured in releases/2.0/sys.config: .. code-block:: erlang @@ -173,44 +182,47 @@ Configure log handlers: ]} ]} -emqttd Application ------------------- +--------------- +etc/emqttd.conf +--------------- -The MQTT broker is implemented by erlang 'emqttd' application: +This is the main configuration file for emqttd broker. + +File Syntax +----------- + +The file uses the Erlang term syntax which is like rebar.config or relx.config: + +1. [ ]: List, seperated by comma +2. { }: Tuple, Usually {Env, Value} +3. % : comment + +MQTT Protocol Parameters +------------------------ + +Maximum ClientId Length +....................... .. code-block:: erlang - {emqttd, [ - %% Authentication and Authorization - {access, [ - ... - ]}, - %% MQTT Protocol Options - {mqtt, [ - ... - ]}, - %% Broker Options - {broker, [ - ... - ]}, - %% Modules - {modules, [ - ... - ]}, - %% Plugins - {plugins, [ - ... - ]}, + %% Max ClientId Length Allowed. + {mqtt_max_clientid_len, 512}. - %% Listeners - {listeners, [ - ... - ]}, +Maximum Packet Size +................... - %% Erlang System Monitor - {sysmon, [ - ]} - ]} +.. code-block:: erlang + + %% Max Packet Size Allowed, 64K by default. + {mqtt_max_packet_size, 65536}. + +MQTT Client Idle Timeout +........................ + +.. code-block:: erlang + + %% Client Idle Timeout. + {mqtt_client_idle_timeout, 30}. % Second Pluggable Authentication ------------------------ @@ -221,54 +233,44 @@ The broker provides Username, ClientId, LDAP and anonymous authentication module .. code-block:: erlang - %% Authetication. Anonymous Default - {auth, [ - %% Authentication with username, password - %% Add users: ./bin/emqttd_ctl users add Username Password - %% {username, [{"test", "public"}]}, + %%-------------------------------------------------------------------- + %% Authentication + %%-------------------------------------------------------------------- - %% Authentication with clientid - % {clientid, [{password, no}, {file, "etc/clients.config"}]}, + %% Anonymous: Allow all + {auth, anonymous, []}. - %% Authentication with LDAP - % {ldap, [ - % {servers, ["localhost"]}, - % {port, 389}, - % {timeout, 30}, - % {user_dn, "uid=$u,ou=People,dc=example,dc=com"}, - % {ssl, fasle}, - % {sslopts, [ - % {"certfile", "ssl.crt"}, - % {"keyfile", "ssl.key"}]} - % ]}, + %% Authentication with username, password + {auth, username, [{passwd, "etc/modules/passwd.conf"}]}. - %% Allow all - {anonymous, []} - ]}, + %% Authentication with clientId + {auth, clientid, [{config, "etc/modules/client.conf"}, {password, no}]}. The modules enabled at the same time compose an authentication chain:: - ---------------- ---------------- ------------- - Client --> | Username | -ignore-> | ClientID | -ignore-> | Anonymous | - ---------------- ---------------- ------------- + ---------------- ---------------- -------------- + Client --> | Anonymous | -ignore-> | Username | -ignore-> | ClientID | + ---------------- ---------------- -------------- | | | \|/ \|/ \|/ allow | deny allow | deny allow | deny -.. NOTE:: There are also MySQL、PostgreSQL、Redis、MongoDB Authentication Plugins. +.. NOTE:: There are also MySQL, Postgre, Redis, MongoDB and HTTP Authentication Plugins. Username Authentication ....................... .. code-block:: erlang - {username, [{client1, "passwd1"}, {client2, "passwd2"}]}, + %% Authentication with username, password + {auth, username, [{passwd, "etc/modules/passwd.conf"}]}. Two ways to configure users: -1. Configure username and plain password directly:: +1. Configure username and plain password in etc/modules/passwd.conf:: - {username, [{client1, "passwd1"}, {client2, "passwd2"}]}, + {"user1", "passwd1"}. + {"user2", "passwd2"}. 2. Add user by './bin/emqttd_ctl users' command:: @@ -279,388 +281,34 @@ ClientID Authentication .. code-block:: erlang - {clientid, [{password, no}, {file, "etc/clients.config"}]}, + %% Authentication with clientId + {auth, clientid, [{config, "etc/modules/client.conf"}, {password, no}]}. Configure ClientIDs in etc/clients.config:: - testclientid0 - testclientid1 127.0.0.1 - testclientid2 192.168.0.1/24 - -LDAP Authentication -................... - -.. code-block:: erlang - - {ldap, [ - {servers, ["localhost"]}, - {port, 389}, - {timeout, 30}, - {user_dn, "uid=$u,ou=People,dc=example,dc=com"}, - {ssl, fasle}, - {sslopts, [ - {"certfile", "ssl.crt"}, - {"keyfile", "ssl.key"}]} - ]}, - + "testclientid0". + {"testclientid1", "127.0.0.1"}. + {"testclientid2", "192.168.0.1/24"}. Anonymous Authentication ........................ Allow any client to connect to the broker:: - {anonymous, []} + %% Anonymous: Allow all + {auth, anonymous, []}. - -ACL ---- +ACL(Authorization) +------------------ Enable the default ACL module: .. code-block:: erlang - {acl, [ - %% Internal ACL module - {internal, [{file, "etc/acl.config"}, {nomatch, allow}]} - ]} + %% Internal ACL config + {acl, internal, [{config, "etc/modules/acl.conf"}, {nomatch, allow}]}. -MQTT Packet and ClientID ------------------------- - -.. code-block:: erlang - - {packet, [ - - %% Max ClientId Length Allowed - {max_clientid_len, 1024}, - - %% Max Packet Size Allowed, 64K default - {max_packet_size, 65536} - ]}, - -MQTT Client Idle Timeout ------------------------- - -.. code-block:: erlang - - {client, [ - %% Socket is connected, but no 'CONNECT' packet received - {idle_timeout, 10} - ]}, - -MQTT Session ------------- - -.. code-block:: erlang - - {session, [ - %% Max number of QoS 1 and 2 messages that can be “in flight” at one time. - %% 0 means no limit - {max_inflight, 100}, - - %% Retry interval for unacked QoS1/2 messages. - {unack_retry_interval, 20}, - - %% Awaiting PUBREL Timeout - {await_rel_timeout, 20}, - - %% Max Packets that Awaiting PUBREL, 0 means no limit - {max_awaiting_rel, 0}, - - %% Interval of Statistics Collection(seconds) - {collect_interval, 20}, - - %% Expired after 2 day (unit: minute) - {expired_after, 2880} - - ]}, - -Session parameters: - -+----------------------+----------------------------------------------------------+ -| max_inflight | Max number of QoS1/2 messages that can be delivered in | -| | the same time | -+----------------------+----------------------------------------------------------+ -| unack_retry_interval | Retry interval for unacked QoS1/2 messages. | -+----------------------+----------------------------------------------------------+ -| await_rel_timeout | Awaiting PUBREL Timeout | -+----------------------+----------------------------------------------------------+ -| max_awaiting_rel | Max number of Packets that Awaiting PUBREL | -+----------------------+----------------------------------------------------------+ -| collect_interval | Interval of Statistics Collection | -+----------------------+----------------------------------------------------------+ -| expired_after | Expired after (unit: minute) | -+----------------------+----------------------------------------------------------+ - -MQTT Message Queue ------------------- - -The message queue of session stores: - -1. Offline messages for persistent session. - -2. Pending messages for inflight window is full - -Queue parameters: - -.. code-block:: erlang - - {queue, [ - %% simple | priority - {type, simple}, - - %% Topic Priority: 0~255, Default is 0 - %% {priority, [{"topic/1", 10}, {"topic/2", 8}]}, - - %% Max queue length. Enqueued messages when persistent client disconnected, - %% or inflight window is full. - {max_length, infinity}, - - %% Low-water mark of queued messages - {low_watermark, 0.2}, - - %% High-water mark of queued messages - {high_watermark, 0.6}, - - %% Queue Qos0 messages? - {queue_qos0, true} - ]} - -+----------------------+---------------------------------------------------+ -| type | Queue type: simple or priority | -+----------------------+---------------------------------------------------+ -| priority | Topic priority | -+----------------------+---------------------------------------------------+ -| max_length | Max Queue size, infinity means no limit | -+----------------------+---------------------------------------------------+ -| low_watermark | Low watermark | -+----------------------+---------------------------------------------------+ -| high_watermark | High watermark | -+----------------------+---------------------------------------------------+ -| queue_qos0 | If Qos0 message queued? | -+----------------------+---------------------------------------------------+ - -Sys Interval of Broker ------------------------ - -.. code-block:: erlang - - %% System interval of publishing $SYS messages - {sys_interval, 60}, - -Retained messages ------------------ - -.. code-block:: erlang - - {retained, [ - %% Expired after seconds, never expired if 0 - {expired_after, 0}, - - %% Maximum number of retained messages - {max_message_num, 100000}, - - %% Max Payload Size of retained message - {max_playload_size, 65536} - ]}, - -PubSub and Router ------------------ - -.. code-block:: erlang - - {pubsub, [ - %% PubSub Pool - {pool_size, 8}, - - %% Subscription: true | false - {subscription, true}, - - %% Route aging time(seconds) - {route_aging, 5} - ]}, - -Bridge Parameters ------------------ - -.. code-block:: erlang - - {bridge, [ - %% Bridge Queue Size - {max_queue_len, 10000}, - - %% Ping Interval of bridge node - {ping_down_interval, 1} - ]} - - -Enable Modules --------------- - -'presence' module will publish presence message to $SYS topic when a client connected or disconnected:: - - {presence, [{qos, 0}]}, - -'subscription' module forces the client to subscribe some topics when connected to the broker: - -.. code-block:: erlang - - %% Subscribe topics automatically when client connected - {subscription, [ - %% Subscription from stored table - stored, - - %% $u will be replaced with username - {"$Q/username/$u", 1}, - - %% $c will be replaced with clientid - {"$Q/client/$c", 1} - ]} - -'rewrite' module supports to rewrite the topic path: - -.. code-block:: erlang - - %% Rewrite rules - {rewrite, [{file, "etc/rewrite.config"}]} - -Plugins Folder --------------- - -.. code-block:: erlang - - {plugins, [ - %% Plugin App Library Dir - {plugins_dir, "./plugins"}, - - %% File to store loaded plugin names. - {loaded_file, "./data/loaded_plugins"} - ]}, - - -TCP Listeners -------------- - -Configure the TCP listeners for MQTT, MQTT(SSL) and HTTP Protocols. - -The most important parameter is 'max_clients' - max concurrent clients allowed. - -The TCP Ports occupied by emqttd broker by default: - -+-----------+-----------------------------------+ -| 1883 | MQTT Port | -+-----------+-----------------------------------+ -| 8883 | MQTT(SSL) Port | -+-----------+-----------------------------------+ -| 8083 | MQTT(WebSocket), HTTP API Port | -+-----------+-----------------------------------+ - -.. code-block:: erlang - - {listeners, [ - - {mqtt, 1883, [ - %% Size of acceptor pool - {acceptors, 16}, - - %% Maximum number of concurrent clients - {max_clients, 8192}, - - %% Socket Access Control - {access, [{allow, all}]}, - - %% Connection Options - {connopts, [ - %% Rate Limit. Format is 'burst, rate', Unit is KB/Sec - %% {rate_limit, "100,10"} %% 100K burst, 10K rate - ]}, - - %% Socket Options - {sockopts, [ - %Set buffer if hight thoughtput - %{recbuf, 4096}, - %{sndbuf, 4096}, - %{buffer, 4096}, - %{nodelay, true}, - {backlog, 1024} - ]} - ]}, - - {mqtts, 8883, [ - %% Size of acceptor pool - {acceptors, 4}, - - %% Maximum number of concurrent clients - {max_clients, 512}, - - %% Socket Access Control - {access, [{allow, all}]}, - - %% SSL certificate and key files - {ssl, [{certfile, "etc/ssl/ssl.crt"}, - {keyfile, "etc/ssl/ssl.key"}]}, - - %% Socket Options - {sockopts, [ - {backlog, 1024} - %{buffer, 4096}, - ]} - ]}, - %% WebSocket over HTTPS Listener - %% {https, 8083, [ - %% %% Size of acceptor pool - %% {acceptors, 4}, - %% %% Maximum number of concurrent clients - %% {max_clients, 512}, - %% %% Socket Access Control - %% {access, [{allow, all}]}, - %% %% SSL certificate and key files - %% {ssl, [{certfile, "etc/ssl/ssl.crt"}, - %% {keyfile, "etc/ssl/ssl.key"}]}, - %% %% Socket Options - %% {sockopts, [ - %% %{buffer, 4096}, - %% {backlog, 1024} - %% ]} - %%]}, - - %% HTTP and WebSocket Listener - {http, 8083, [ - %% Size of acceptor pool - {acceptors, 4}, - %% Maximum number of concurrent clients - {max_clients, 64}, - %% Socket Access Control - {access, [{allow, all}]}, - %% Socket Options - {sockopts, [ - {backlog, 1024} - %{buffer, 4096}, - ]} - ]} - ]}, - -Listener Parameters: - -+-------------+----------------------------------------------------------------+ -| acceptors | TCP Acceptor Pool | -+-------------+----------------------------------------------------------------+ -| max_clients | Maximum number of concurrent TCP connections allowed | -+-------------+----------------------------------------------------------------+ -| access | Access Control by IP, for example: [{allow, "192.168.1.0/24"}] | -+-------------+----------------------------------------------------------------+ -| connopts | Rate Limit Control, for example: {rate_limit, "100,10"} | -+-------------+----------------------------------------------------------------+ -| sockopts | TCP Socket parameters | -+-------------+----------------------------------------------------------------+ - -.. _config_acl: - --------------- -etc/acl.config --------------- - -The 'etc/acl.config' is the default ACL config for emqttd broker. The rules by default: +Define ACL rules in etc/modules/acl.conf. The rules by default: .. code-block:: erlang @@ -686,35 +334,194 @@ An ACL rule is an Erlang tuple. The Access control module of emqttd broker match \|/ \|/ \|/ allow | deny allow | deny allow | deny -.. _config_rewrite: - ------------------- -etc/clients.config ------------------- - -Enable ClientId Authentication in 'etc/emqttd.config': +Sys Interval of Broker +---------------------- .. code-block:: erlang - {auth, [ - %% Authentication with clientid - {clientid, [{password, no}, {file, "etc/clients.config"}]} - ]}, + %% System interval of publishing $SYS messages + {broker_sys_interval, 60}. -Configure all allowed ClientIDs, IP Addresses in etc/clients.config:: +Retained Message Configuration +------------------------------ - testclientid0 - testclientid1 127.0.0.1 - testclientid2 192.168.0.1/24 +Expiration of Retained Message +............................... ------------------- -etc/rewrite.config ------------------- +.. code:: erlang -The Rewrite Rules for emqttd_mod_rewrite: + %% Expired after seconds, never expired if 0 + {retained_expired_after, 0}. + +Maximum Number of Retained Message +................................... + +.. code:: erlang + + %% Max number of retained messages + {retained_max_message_num, 100000}. + +Maximum Size of Retained Message +................................ + +.. code:: erlang + + %% Max Payload Size of retained message + {retained_max_playload_size, 65536}. + +MQTT Session +------------ .. code-block:: erlang + %% Max number of QoS 1 and 2 messages that can be “inflight” at one time. + %% 0 means no limit + {session_max_inflight, 100}. + + %% Retry interval for redelivering QoS1/2 messages. + {session_unack_retry_interval, 60}. + + %% Awaiting PUBREL Timeout + {session_await_rel_timeout, 20}. + + %% Max Packets that Awaiting PUBREL, 0 means no limit + {session_max_awaiting_rel, 0}. + + %% Statistics Collection Interval(seconds) + {session_collect_interval, 0}. + + %% Expired after 2 day (unit: minute) + {session_expired_after, 2880}. + +Session parameters: + ++------------------------------+----------------------------------------------------------+ +| session_max_inflight | Max number of QoS1/2 messages that can be delivered in | +| | the same time | ++------------------------------+----------------------------------------------------------+ +| session_unack_retry_interval | Retry interval for unacked QoS1/2 messages. | ++------------------------------+----------------------------------------------------------+ +| session_await_rel_timeout | Awaiting PUBREL Timeout | ++------------------------------+----------------------------------------------------------+ +| session_max_awaiting_rel | Max number of Packets that Awaiting PUBREL | ++------------------------------+----------------------------------------------------------+ +| session_collect_interval | Interval of Statistics Collection | ++------------------------------+----------------------------------------------------------+ +| session_expired_after | Expired after (unit: minute) | ++------------------------------+----------------------------------------------------------+ + +MQTT Message Queue +------------------ + +The message queue of session stores: + +1. Offline messages for persistent session. + +2. Pending messages for inflight window is full + +Queue parameters: + +.. code-block:: erlang + + %% Type: simple | priority + {queue_type, simple}. + + %% Topic Priority: 0~255, Default is 0 + %% {queue_priority, [{"topic/1", 10}, {"topic/2", 8}]}. + + %% Max queue length. Enqueued messages when persistent client disconnected, + %% or inflight window is full. + {queue_max_length, infinity}. + + %% Low-water mark of queued messages + {queue_low_watermark, 0.2}. + + %% High-water mark of queued messages + {queue_high_watermark, 0.6}. + + %% Queue Qos0 messages? + {queue_qos0, true}. + ++----------------------+---------------------------------------------------+ +| queue_type | Queue type: simple or priority | ++----------------------+---------------------------------------------------+ +| queue_priority | Topic priority | ++----------------------+---------------------------------------------------+ +| queue_max_length | Max Queue size, infinity means no limit | ++----------------------+---------------------------------------------------+ +| queue_low_watermark | Low watermark | ++----------------------+---------------------------------------------------+ +| queue_high_watermark | High watermark | ++----------------------+---------------------------------------------------+ +| queue_qos0 | If Qos0 message queued? | ++----------------------+---------------------------------------------------+ + +PubSub and Router +----------------- + +PubSub Pool Size +................ + +.. code-block:: erlang + + %% PubSub Pool Size. Default should be scheduler numbers. + {pubsub_pool_size, 8}. + +MQTT Bridge Parameters +---------------------- + +Max MQueue Size of Bridge +......................... + +.. code:: erlang + + %% TODO: Bridge Queue Size + {bridge_max_queue_len, 10000}. + +Ping Interval of Bridge +....................... + +.. code:: erlang + + %% Ping Interval of bridge node + {bridge_ping_down_interval, 1}. % second + +Extended Modules +---------------- + +Presence Module +............... + +'presence' module will publish presence message to $SYS topic when a client connected or disconnected: + +.. code:: erlang + + %% Client presence management module. Publish presence messages when + %% client connected or disconnected. + {module, presence, [{qos, 0}]}. + +Subscription Module +................... + +'subscription' module forces the client to subscribe some topics when connected to the broker: + +.. code:: erlang + + %% Subscribe topics automatically when client connected + {module, subscription, [{"$client/$c", 1}]}. + +Rewrite Module +.............. + +'rewrite' module supports to rewrite the topic path: + +.. code:: erlang + + %% [Rewrite](https://github.com/emqtt/emqttd/wiki/Rewrite) + {module, rewrite, [{config, "etc/modules/rewrite.conf"}]}. + +Configure rewrite rules in etc/modules/rewrite.conf:: + {topic, "x/#", [ {rewrite, "^x/y/(.+)$", "z/y/$1"}, {rewrite, "^x/(.+)$", "y/$1"} @@ -723,3 +530,161 @@ The Rewrite Rules for emqttd_mod_rewrite: {topic, "y/+/z/#", [ {rewrite, "^y/(.+)/z/(.+)$", "y/z/$2"} ]}. + +Plugins Folder +-------------- + +.. code:: erlang + + %% Dir of plugins' config + {plugins_etc_dir, "etc/plugins/"}. + + %% File to store loaded plugin names. + {plugins_loaded_file, "data/loaded_plugins"}. + + +TCP Listeners +------------- + +Configure the TCP listeners for MQTT, MQTT(SSL) and HTTP Protocols. + +The most important parameter is 'max_clients' - max concurrent clients allowed. + +The TCP Ports occupied by emqttd broker by default: + ++-----------+-----------------------------------+ +| 1883 | MQTT Port | ++-----------+-----------------------------------+ +| 8883 | MQTT(SSL) Port | ++-----------+-----------------------------------+ +| 8083 | MQTT(WebSocket), HTTP API Port | ++-----------+-----------------------------------+ + +.. code-block:: erlang + +Listener Parameters: + ++-------------+----------------------------------------------------------------+ +| acceptors | TCP Acceptor Pool | ++-------------+----------------------------------------------------------------+ +| max_clients | Maximum number of concurrent TCP connections allowed | ++-------------+----------------------------------------------------------------+ +| access | Access Control by IP, for example: [{allow, "192.168.1.0/24"}] | ++-------------+----------------------------------------------------------------+ +| connopts | Rate Limit Control, for example: {rate_limit, "100,10"} | ++-------------+----------------------------------------------------------------+ +| sockopts | TCP Socket parameters | ++-------------+----------------------------------------------------------------+ + +1883 - Plain MQTT +................. + +.. code-block:: erlang + + %% Plain MQTT + {listener, mqtt, 1883, [ + %% Size of acceptor pool + {acceptors, 16}, + + %% Maximum number of concurrent clients + {max_clients, 512}, + + %% Mount point prefix + %% {mount_point, "prefix/"}, + + %% Socket Access Control + {access, [{allow, all}]}, + + %% Connection Options + {connopts, [ + %% Rate Limit. Format is 'burst, rate', Unit is KB/Sec + %% {rate_limit, "100,10"} %% 100K burst, 10K rate + ]}, + + %% Socket Options + {sockopts, [ + %Set buffer if hight thoughtput + %{recbuf, 4096}, + %{sndbuf, 4096}, + %{buffer, 4096}, + %{nodelay, true}, + {backlog, 1024} + ]} + ]}. + +8883 - MQTT(SSL) +................ + +.. code-block:: erlang + + %% MQTT/SSL + {listener, mqtts, 8883, [ + %% Size of acceptor pool + {acceptors, 4}, + + %% Maximum number of concurrent clients + {max_clients, 512}, + + %% Mount point prefix + %% {mount_point, "secure/"}, + + %% Socket Access Control + {access, [{allow, all}]}, + + %% SSL certificate and key files + {ssl, [{certfile, "etc/ssl/ssl.crt"}, + {keyfile, "etc/ssl/ssl.key"}]}, + + %% Socket Options + {sockopts, [ + {backlog, 1024} + %{buffer, 4096}, + ]} + ]}. + +8083 - MQTT(WebSocket) +...................... + +.. code-block:: erlang + + %% HTTP and WebSocket Listener + {listener, http, 8083, [ + %% Size of acceptor pool + {acceptors, 4}, + + %% Maximum number of concurrent clients + {max_clients, 64}, + + %% Socket Access Control + {access, [{allow, all}]}, + + %% Socket Options + {sockopts, [ + {backlog, 1024} + %{buffer, 4096}, + ]} + ]}. + +Erlang VM Monitor +----------------- + +.. code:: erlang + + %% Long GC, don't monitor in production mode for: + %% https://github.com/erlang/otp/blob/feb45017da36be78d4c5784d758ede619fa7bfd3/erts/emulator/beam/erl_gc.c#L421 + + {sysmon_long_gc, false}. + + %% Long Schedule(ms) + {sysmon_long_schedule, 240}. + + %% 8M words. 32MB on 32-bit VM, 64MB on 64-bit VM. + %% 8 * 1024 * 1024 + {sysmon_large_heap, 8388608}. + + %% Busy Port + {sysmon_busy_port, false}. + + %% Busy Dist Port + {sysmon_busy_dist_port, true}. + diff --git a/docs/source/design.rst b/docs/source/design.rst index a9d081cc2..adc1f10b8 100644 --- a/docs/source/design.rst +++ b/docs/source/design.rst @@ -15,6 +15,17 @@ The emqttd broker 1.0 is more like a network Switch or Router, not a traditional .. image:: _static/images/concept.png +The EMQ 2.0 seperated the Message Flow Plane and Monitor/Control Plane, the Architecture is something like:: + + Control Plane + -------------------- + | | + FrontEnd -> | Flow Plane | -> BackEnd + | | + Session Router + --------------------- + Monitor Plane + Design Philosophy ----------------- @@ -478,3 +489,32 @@ http://github.com/emqtt/emqttd_plugin_template .. _eSockd: https://github.com/emqtt/esockd .. _Chain-of-responsibility_pattern: https://en.wikipedia.org/wiki/Chain-of-responsibility_pattern .. _emqttd_plugin_template: https://github.com/emqtt/emqttd_plugin_template/blob/master/src/emqttd_plugin_template.erl + +----------------- +Mnesia/ETS Tables +----------------- + ++--------------------+--------+----------------------------------------+ +| Table | Type | Description | ++====================+========+========================================+ +| mqtt_trie | mnesia | Trie Table | ++--------------------+--------+----------------------------------------+ +| mqtt_trie_node | mnesia | Trie Node Table | ++--------------------+--------+----------------------------------------+ +| mqtt_route | mnesia | Global Route Table | ++--------------------+--------+----------------------------------------+ +| mqtt_local_route | mnesia | Local Route Table | ++--------------------+--------+----------------------------------------+ +| mqtt_pubsub | ets | PubSub Tab | ++--------------------+--------+----------------------------------------+ +| mqtt_subscriber | ets | Subscriber Tab | ++--------------------+--------+----------------------------------------+ +| mqtt_subscription | ets | Subscription Tab | ++--------------------+--------+----------------------------------------+ +| mqtt_session | mnesia | Global Session Table | ++--------------------+--------+----------------------------------------+ +| mqtt_local_session | ets | Local Session Table | ++--------------------+--------+----------------------------------------+ +| mqtt_client | ets | Client Table | ++--------------------+--------+----------------------------------------+ + diff --git a/docs/source/getstarted.rst b/docs/source/getstarted.rst index 55b11164f..e5d0fbc6e 100644 --- a/docs/source/getstarted.rst +++ b/docs/source/getstarted.rst @@ -35,6 +35,8 @@ Features * MQTT Over WebSocket(SSL) * HTTP Publish API * STOMP protocol +* MQTT-SN Protocol +* CoAP Protocol * STOMP over SockJS * $SYS/# Topics * ClientID Authentication @@ -63,7 +65,7 @@ Installing on Mac, for example: .. code-block:: bash - unzip emqttd-macosx-1.1-beta-20160601.zip && cd emqttd + unzip emqttd-macosx-2.0-beta1-20160830.zip && cd emqttd # Start emqttd ./bin/emqttd start @@ -119,8 +121,6 @@ Modules +-------------------------+--------------------------------------------+ | emqttd_auth_username | Authentication with Username and Password | +-------------------------+--------------------------------------------+ -| emqttd_auth_ldap | Authentication with LDAP | -+-------------------------+--------------------------------------------+ | emqttd_mod_presence | Publish presence message to $SYS topics | | | when client connected or disconnected | +-------------------------+--------------------------------------------+ @@ -136,22 +136,16 @@ Enable 'emqttd_auth_username' module: .. code-block:: erlang - {access, [ - %% Authetication. Anonymous Default - {auth, [ - %% Authentication with username, password - {username, []}, - - ... + %% Authentication with username, password + {auth, username, [{passwd, "etc/modules/passwd.conf"}]}. Enable 'emqttd_mod_presence' module: .. code-block:: erlang - {modules, [ - %% Client presence management module. - %% Publish messages when client connected or disconnected - {presence, [{qos, 0}]} + %% Client presence management module. Publish presence messages when + %% client connected or disconnected. + {module, presence, [{qos, 0}]}. Plugins ------- @@ -163,17 +157,21 @@ A plugin is an Erlang application to extend the emqttd broker. +----------------------------+-----------------------------------+ | `emqttd_dashboard`_ | Web Dashboard | +----------------------------+-----------------------------------+ +| `emqttd_auth_ldap`_ | LDAP Auth Plugin | ++----------------------------+-----------------------------------+ | `emqttd_auth_http`_ | Authentication/ACL with HTTP API | +----------------------------+-----------------------------------+ -| `emqttd_plugin_mysql`_ | Authentication with MySQL | +| `emqttd_auth_mysql` _ | Authentication with MySQL | +----------------------------+-----------------------------------+ -| `emqttd_plugin_pgsql`_ | Authentication with PostgreSQL | +| `emqttd_auth_pgsql`_ | Authentication with PostgreSQL | +----------------------------+-----------------------------------+ -| `emqttd_plugin_redis`_ | Authentication with Redis | +| `emqttd_auth_redis`_ | Authentication with Redis | +----------------------------+-----------------------------------+ | `emqttd_plugin_mongo`_ | Authentication with MongoDB | +----------------------------+-----------------------------------+ -| `emqttd_stomp`_ | STOMP Protocol Plugin | +| `emqttd_sn`_ | MQTT-SN Protocol Plugin | ++----------------------------+-----------------------------------+ +| `emqttd_stomp`_ | STOMP Protocol Plugin | +----------------------------+-----------------------------------+ | `emqttd_sockjs`_ | SockJS(Stomp) Plugin | +----------------------------+-----------------------------------+ @@ -182,9 +180,9 @@ A plugin is an Erlang application to extend the emqttd broker. A plugin could be enabled by 'bin/emqttd_ctl plugins load' command. -For example, enable 'emqttd_plugin_pgsql' plugin:: +For example, enable 'emqttd_auth_pgsql' plugin:: - ./bin/emqttd_ctl plugins load emqttd_plugin_pgsql + ./bin/emqttd_ctl plugins load emqttd_auth_pgsql ----------------------- One Million Connections @@ -238,26 +236,27 @@ emqttd/etc/vm.args:: emqttd broker ------------- -emqttd/etc/emqttd.config: +emqttd/etc/emqttd.conf: .. code-block:: erlang - {mqtt, 1883, [ - %% Size of acceptor pool - {acceptors, 64}, + {listener, mqtt, 1883, [ + %% Size of acceptor pool + {acceptors, 64}, - %% Maximum number of concurrent clients - {max_clients, 1000000}, + %% Maximum number of concurrent clients + {max_clients, 1000000}, - %% Socket Access Control - {access, [{allow, all}]}, + %% Socket Access Control + {access, [{allow, all}]}, - %% Connection Options - {connopts, [ - %% Rate Limit. Format is 'burst, rate', Unit is KB/Sec - %% {rate_limit, "100,10"} %% 100K burst, 10K rate - ]}, - ... + %% Connection Options + {connopts, [ + %% Rate Limit. Format is 'burst, rate', Unit is KB/Sec + %% {rate_limit, "100,10"} %% 100K burst, 10K rate + ]}, + ... + ]}. Test Client ----------- @@ -291,11 +290,15 @@ GitHub: https://github.com/emqtt .. _emqttd_plugin_template: https://github.com/emqtt/emqttd_plugin_template .. _emqttd_dashboard: https://github.com/emqtt/emqttd_dashboard +.. _emqttd_auth_ldap: https://github.com/emqtt/emqttd_auth_ldap .. _emqttd_auth_http: https://github.com/emqtt/emqttd_auth_http -.. _emqttd_plugin_mysql: https://github.com/emqtt/emqttd_plugin_mysql -.. _emqttd_plugin_pgsql: https://github.com/emqtt/emqttd_plugin_pgsql -.. _emqttd_plugin_redis: https://github.com/emqtt/emqttd_plugin_redis -.. _emqttd_plugin_mongo: https://github.com/emqtt/emqttd_plugin_mongo +.. _emqttd_auth_mysql: https://github.com/emqtt/emqttd_plugin_mysql +.. _emqttd_auth_pgsql: https://github.com/emqtt/emqttd_plugin_pgsql +.. _emqttd_auth_redis: https://github.com/emqtt/emqttd_plugin_redis +.. _emqttd_auth_mongo: https://github.com/emqtt/emqttd_plugin_mongo +.. _emqttd_reloader: https://github.com/emqtt/emqttd_reloader .. _emqttd_stomp: https://github.com/emqtt/emqttd_stomp .. _emqttd_sockjs: https://github.com/emqtt/emqttd_sockjs .. _emqttd_recon: https://github.com/emqtt/emqttd_recon +.. _emqttd_sn: https://github.com/emqtt/emqttd_sn + diff --git a/docs/source/index.rst b/docs/source/index.rst index 4051035b1..2db72ecdd 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -35,8 +35,6 @@ Sensors, Mobiles, Web Browsers and Application Servers could be connected by emq | Author: | Feng Lee | +---------------+-----------------------------------------+ -.. NOTE:: MQTT-SN,CoAP Protocols are planned to 1.x release. - Contents: .. toctree:: diff --git a/docs/source/install.rst b/docs/source/install.rst index 8bb68e4f8..83a51d2bd 100644 --- a/docs/source/install.rst +++ b/docs/source/install.rst @@ -35,7 +35,7 @@ Download binary packages from: http://emqtt.io/downloads The package name consists of platform, version and release time. -For example: emqttd-centos64-1.1-beta-20160601.zip +For example: emqttd-centos64-2.0-beta1-20160830.zip .. _install_on_linux: @@ -47,7 +47,7 @@ Download CentOS Package from: http://emqtt.io/downloads/latest/centos, and then .. code-block:: bash - unzip emqttd-centos64-1.1-beta-20160601.zip + unzip emqttd-centos64-2.0-beta-20160830.zip Start the broker in console mode: @@ -80,7 +80,7 @@ If the broker is started successfully, console will print: mqtt listen on 0.0.0.0:1883 with 16 acceptors. mqtts listen on 0.0.0.0:8883 with 4 acceptors. http listen on 0.0.0.0:8083 with 4 acceptors. - Erlang MQTT Broker 1.1 is running now + Erlang MQTT Broker 2.0 is running now Eshell V6.4 (abort with ^G) (emqttd@127.0.0.1)1> @@ -100,7 +100,7 @@ Check the running status of the broker: $ ./bin/emqttd_ctl status Node 'emqttd@127.0.0.1' is started - emqttd 1.1 is running + emqttd 2.0 is running Or check the status by URL:: @@ -130,7 +130,7 @@ We could install the broker on Mac OS X to develop and debug MQTT applications. Download Mac Package from: http://emqtt.io/downloads/latest/macosx -Configure 'lager' log level in 'etc/emqttd.config', all MQTT messages recevied/sent will be printed on console: +Configure 'lager' log level in 'releases/2.0/sys.config', all MQTT messages recevied/sent will be printed on console: .. code-block:: erlang @@ -198,15 +198,15 @@ When all dependencies are ready, clone the emqttd project from github.com and bu .. code-block:: bash - git clone https://github.com/emqtt/emqttd.git + git clone https://github.com/emqtt/emqttd-relx.git - cd emqttd + cd emqttd-relx && make - make && make dist + cd _rel/emqttd && ./bin/emqttd console The binary package output in folder:: - rel/emqttd + _rel/emqttd .. _tcp_ports: @@ -228,19 +228,20 @@ The TCP ports used can be configured in etc/emqttd.config: .. code-block:: erlang - {listeners, [ - {mqtt, 1883, [ - ... - ]}, + %% Plain MQTT + {listener, mqtt, 1883, [ + ... + ]}. - {mqtts, 8883, [ - ... - ]}, - %% HTTP and WebSocket Listener - {http, 8083, [ - ... - ]} - ]}, + %% MQTT/SSL + {listener, mqtts, 8883, [ + ... + ]}. + + %% HTTP and WebSocket Listener + {listener, http, 8083, [ + ... + ]}. The 18083 port is used by Web Dashboard of the broker. Default login: admin, Password: public @@ -255,7 +256,7 @@ Two main configuration files of the emqttd broker: +-------------------+-----------------------------------+ | etc/vm.args | Erlang VM Arguments | +-------------------+-----------------------------------+ -| etc/emqttd.config | emqttd broker Config | +| etc/emqttd.conf | emqttd broker Config | +-------------------+-----------------------------------+ Two important parameters in etc/vm.args: @@ -277,17 +278,18 @@ The maximum number of allowed MQTT clients: .. code-block:: erlang - {listeners, [ - {mqtt, 1883, [ - %% TCP Acceptor Pool - {acceptors, 16}, + %% Plain MQTT + {listener, mqtt, 1883, [ - %% Maximum number of concurrent MQTT clients - {max_clients, 8192}, + %% Size of acceptor pool + {acceptors, 16}, - ... + %% Maximum number of concurrent clients + {max_clients, 8192}, - ]}, + ... + + ]}. .. _init_d_emqttd: diff --git a/docs/source/plugins.rst b/docs/source/plugins.rst index 6c4fa552a..ab4543e06 100644 --- a/docs/source/plugins.rst +++ b/docs/source/plugins.rst @@ -7,24 +7,28 @@ Plugins The emqttd broker could be extended by plugins. Users could develop plugins to customize authentication, ACL and functions of the broker, or integrate the broker with other systems. -The plugins that emqtt project released: +The plugins that emqttd 2.0 released: +---------------------------+---------------------------+ | Plugin | Description | +===========================+===========================+ +| `emqttd_dashboard`_ | Web Dashboard | ++---------------------------+---------------------------+ | `emqttd_plugin_template`_ | Template Plugin | +---------------------------+---------------------------+ -| `emqttd_dashboard`_ | Web Dashboard | +| `emqttd_auth_ldap`_ | LDAP Auth | +---------------------------+---------------------------+ | `emqttd_auth_http`_ | HTTP Auth/ACL Plugin | +---------------------------+---------------------------+ -| `emqttd_plugin_mysql`_ | MySQL Auth/ACL Plugin | +| `emqttd_auth_mysql`_ | MySQL Auth/ACL Plugin | +---------------------------+---------------------------+ -| `emqttd_plugin_pgsql`_ | PostgreSQL Auth/ACL Plugin| +| `emqttd_auth_pgsql`_ | PostgreSQL Auth/ACL Plugin| +---------------------------+---------------------------+ -| `emqttd_plugin_redis`_ | Redis Auth/ACL Plugin | +| `emqttd_auth_redis`_ | Redis Auth/ACL Plugin | +---------------------------+---------------------------+ -| `emqttd_plugin_mongo`_ | MongoDB Auth/ACL Plugin | +| `emqttd_auth_mongo`_ | MongoDB Auth/ACL Plugin | ++---------------------------+---------------------------+ +| `emqttd_sn`_ | MQTT-SN Protocol Plugin | +---------------------------+---------------------------+ | `emqttd_stomp`_ | STOMP Protocol Plugin | +---------------------------+---------------------------+ @@ -39,17 +43,9 @@ The plugins that emqtt project released: emqttd_plugin_template - Template Plugin ---------------------------------------- -A plugin is just a normal Erlang application under the 'emqttd/plugins' folder. Each plugin has e configuration file: 'etc/plugin.config'. +A plugin is just a normal Erlang application which has its own configuration file: 'etc/.config'. -plugins/emqttd_plugin_template is a demo plugin. The folder structure: - -+------------------------+---------------------------+ -| File | Description | -+========================+===========================+ -| etc/plugin.config | Plugin config file | -+------------------------+---------------------------+ -| ebin/ | Erlang program files | -+------------------------+---------------------------+ +emqttd_plugin_template is a demo plugin. Load, unload Plugin ------------------- @@ -78,22 +74,51 @@ The Web Dashboard for emqttd broker. The plugin will be loaded automatically whe .. image:: _static/images/dashboard.png -Configure Dashboard -------------------- +Configure Dashboard Plugin +-------------------------- -emqttd_dashboard/etc/plugin.config: +etc/plugins/emqttd_dashboard.conf: .. code-block:: erlang - [ - {emqttd_dashboard, [ - {listener, - {emqttd_dashboard, 18083, [ - {acceptors, 4}, - {max_clients, 512}]} - } + {listener, + {dashboard, 18083, [ + {acceptors, 4}, + {max_clients, 512} ]} - ]. + }. + +---------------------------------- +emqttd_auth_ldap: LDAP Auth Plugin +---------------------------------- + +LDAP Auth Plugin: https://github.com/emqtt/emqttd_auth_ldap + +.. NOTE:: Supported in 2.0-beta1 release + +Configure LDAP Plugin +--------------------- + +etc/plugins/emqttd_auth_ldap.conf: + +.. code-block:: erlang + + {ldap, [ + {servers, ["localhost"]}, + {port, 389}, + {timeout, 30}, + {user_dn, "uid=$u,ou=People,dc=example,dc=com"}, + {ssl, fasle}, + {sslopts, [ + {certfile, "ssl.crt"}, + {keyfile, "ssl.key"} + ]} + ]}. + +Load LDAP Plugin +---------------- + +./bin/emqttd_ctl plugins load emqttd_auth_ldap --------------------------------------- emqttd_auth_http - HTTP Auth/ACL Plugin @@ -103,61 +128,57 @@ MQTT Authentication/ACL with HTTP API: https://github.com/emqtt/emqttd_auth_http .. NOTE:: Supported in 1.1 release -Configure emqttd_auth_http/etc/plugin.config --------------------------------------------- +Configure HTTP Auth/ACL Plugin +------------------------------ -.. code:: erlang +etc/plugins/emqttd_auth_http.conf: - [ +.. code-block:: erlang - {emqttd_auth_http, [ + %% Variables: %u = username, %c = clientid, %a = ipaddress, %t = topic - %% Variables: %u = username, %c = clientid, %a = ipaddress, %t = topic - - {super_req, [ - {method, post}, - {url, "http://localhost:8080/mqtt/superuser"}, - {params, [ - {username, "%u"}, - {clientid, "%c"} - ]} - ]}, - - {auth_req, [ - {method, post}, - {url, "http://localhost:8080/mqtt/auth"}, - {params, [ - {clientid, "%c"}, - {username, "%u"}, - {password, "%P"} - ]} - ]}, - - %% 'access' parameter: sub = 1, pub = 2 - - {acl_req, [ - {method, post}, - {url, "http://localhost:8080/mqtt/acl"}, - {params, [ - {access, "%A"}, - {username, "%u"}, - {clientid, "%c"}, - {ipaddr, "%a"}, - {topic, "%t"} - ]} - ]} + {super_req, [ + {method, post}, + {url, "http://localhost:8080/mqtt/superuser"}, + {params, [ + {username, "%u"}, + {clientid, "%c"} ]} + ]}. - ]. + {auth_req, [ + {method, post}, + {url, "http://localhost:8080/mqtt/auth"}, + {params, [ + {clientid, "%c"}, + {username, "%u"}, + {password, "%P"} + ]} + ]}. -HTTP API --------- + %% 'access' parameter: sub = 1, pub = 2 + + {acl_req, [ + {method, post}, + {url, "http://localhost:8080/mqtt/acl"}, + {params, [ + {access, "%A"}, + {username, "%u"}, + {clientid, "%c"}, + {ipaddr, "%a"}, + {topic, "%t"} + ]} + ]}. + + +HTTP Auth/ACL API +----------------- Return 200 if ok Return 4xx if unauthorized -Load emqttd_auth_http plugin +Load HTTP Auth/ACL Plugin ---------------------------- .. code:: bash @@ -211,64 +232,57 @@ MQTT ACL Table (6,1,'127.0.0.1',NULL,NULL,2,'#'), (7,1,NULL,'dashboard',NULL,1,'$SYS/#'); -Configure emqttd_plugin_mysql/etc/plugin.config ------------------------------------------------ +Configure MySQL Auth/ACL Plugin +------------------------------- -Configure MySQL host, username, password and database: +etc/plugins/emqttd_plugin_mysql.conf: .. code-block:: erlang - [ + {mysql_pool, [ + %% pool options + {pool_size, 8}, + {auto_reconnect, 1}, - {emqttd_plugin_mysql, [ + %% mysql options + {host, "localhost"}, + {port, 3306}, + {user, ""}, + {password, ""}, + {database, "mqtt"}, + {encoding, utf8}, + {keep_alive, true} + ]}. - {mysql_pool, [ - %% ecpool options - {pool_size, 8}, - {auto_reconnect, 3}, + %% Variables: %u = username, %c = clientid, %a = ipaddress - %% mysql options - {host, "localhost"}, - {port, 3306}, - {user, ""}, - {password, ""}, - {database, "mqtt"}, - {encoding, utf8} - ]}, + %% Superuser Query + {superquery, "select is_superuser from mqtt_user where username = '%u' limit 1"}. - %% Variables: %u = username, %c = clientid, %a = ipaddress + %% Authentication Query: select password only + {authquery, "select password from mqtt_user where username = '%u' limit 1"}. - %% Superuser Query - {superquery, "select is_superuser from mqtt_user where username = '%u' limit 1"}, + %% hash algorithm: plain, md5, sha, sha256, pbkdf2? + {password_hash, sha256}. - %% Authentication Query: select password only - {authquery, "select password from mqtt_user where username = '%u' limit 1"}, + %% select password with salt + %% {authquery, "select password, salt from mqtt_user where username = '%u'"}. - %% hash algorithm: plain, md5, sha, sha256, pbkdf2? - {password_hash, sha256}, + %% sha256 with salt prefix + %% {password_hash, {salt, sha256}}. - %% select password with salt - %% {authquery, "select password, salt from mqtt_user where username = '%u'"}, + %% sha256 with salt suffix + %% {password_hash, {sha256, salt}}. - %% sha256 with salt prefix - %% {password_hash, {salt, sha256}}, + %% '%a' = ipaddress, '%u' = username, '%c' = clientid + %% Comment this query, the acl will be disabled + {aclquery, "select allow, ipaddr, username, clientid, access, topic from mqtt_acl where ipaddr = '%a' or username = '%u' or username = '$all' or clientid = '%c'"}. - %% sha256 with salt suffix - %% {password_hash, {sha256, salt}}, + %% If no ACL rules matched, return... + {acl_nomatch, allow}. - %% '%a' = ipaddress, '%u' = username, '%c' = clientid - %% Comment this query, the acl will be disabled - {aclquery, "select allow, ipaddr, username, clientid, access, topic from mqtt_acl where ipaddr = '%a' or username = '%u' or username = '$all' or clientid = '%c'"}, - - %% If no ACL rules matched, return... - {acl_nomatch, allow} - - ]} - - ]. - -Load emqttd_plugin_mysql plugin -------------------------------- +Load MySQL Auth/ACL plugin +-------------------------- .. code-block:: bash @@ -280,8 +294,8 @@ emqttd_plugin_pgsql - PostgreSQL Auth/ACL Plugin MQTT Authentication, ACL with PostgreSQL Database. -MQTT User Table ---------------- +Postgre MQTT User Table +----------------------- .. code-block:: sql @@ -293,8 +307,8 @@ MQTT User Table salt character varying(40) ); -MQTT ACL Table --------------- +Postgre MQTT ACL Table +---------------------- .. code-block:: sql @@ -317,67 +331,62 @@ MQTT ACL Table (6,1,'127.0.0.1',NULL,NULL,2,'#'), (7,1,NULL,'dashboard',NULL,1,'$SYS/#'); -Configure emqttd_plugin_pgsql/etc/plugin.config +Configure Postgre Auth/ACL Plugin ----------------------------------------------- +Plugin Config: etc/plugins/emqttd_plugin_pgsql.conf. + Configure host, username, password and database of PostgreSQL: .. code-block:: erlang - [ + {pgsql_pool, [ + %% pool options + {pool_size, 8}, + {auto_reconnect, 3}, - {emqttd_plugin_pgsql, [ + %% pgsql options + {host, "localhost"}, + {port, 5432}, + {ssl, false}, + {username, "feng"}, + {password, ""}, + {database, "mqtt"}, + {encoding, utf8} + ]}. - {pgsql_pool, [ - %% ecpool options - {pool_size, 8}, - {auto_reconnect, 3}, + %% Variables: %u = username, %c = clientid, %a = ipaddress - %% pgsql options - {host, "localhost"}, - {port, 5432}, - {ssl, false}, - {username, "feng"}, - {password, ""}, - {database, "mqtt"}, - {encoding, utf8} - ]}, + %% Superuser Query + {superquery, "select is_superuser from mqtt_user where username = '%u' limit 1"}. - %% Variables: %u = username, %c = clientid, %a = ipaddress + %% Authentication Query: select password only + {authquery, "select password from mqtt_user where username = '%u' limit 1"}. - %% Superuser Query - {superquery, "select is_superuser from mqtt_user where username = '%u' limit 1"}, + %% hash algorithm: plain, md5, sha, sha256, pbkdf2? + {password_hash, sha256}. - %% Authentication Query: select password only - {authquery, "select password from mqtt_user where username = '%u' limit 1"}, + %% select password with salt + %% {authquery, "select password, salt from mqtt_user where username = '%u'"}. - %% hash algorithm: plain, md5, sha, sha256, pbkdf2? - {password_hash, sha256}, + %% sha256 with salt prefix + %% {password_hash, {salt, sha256}}. - %% select password with salt - %% {authquery, "select password, salt from mqtt_user where username = '%u'"}, + %% sha256 with salt suffix + %% {password_hash, {sha256, salt}}. - %% sha256 with salt prefix - %% {password_hash, {salt, sha256}}, + %% Comment this query, the acl will be disabled. Notice: don't edit this query! + {aclquery, "select allow, ipaddr, username, clientid, access, topic from mqtt_acl where ipaddr = '%a' or username = '%u' or username = '$all' or clientid = '%c'"}. - %% sha256 with salt suffix - %% {password_hash, {sha256, salt}}, + %% If no rules matched, return... + {acl_nomatch, allow}. - %% Comment this query, the acl will be disabled. Notice: don't edit this query! - {aclquery, "select allow, ipaddr, username, clientid, access, topic from mqtt_acl - where ipaddr = '%a' or username = '%u' or username = '$all' or clientid = '%c'"}, - - %% If no rules matched, return... - {acl_nomatch, allow} - ]} - ]. - -Load emqttd_plugin_pgsql Plugin -------------------------------- +Load Postgre Auth/ACL Plugin +----------------------------- .. code-block:: bash - ./bin/emqttd_ctl plugins load emqttd_plugin_pgsql + ./bin/emqttd_ctl plugins load emqttd_auth_pgsql ------------------------------------------- emqttd_plugin_redis - Redis Auth/ACL Plugin @@ -385,58 +394,56 @@ emqttd_plugin_redis - Redis Auth/ACL Plugin MQTT Authentication, ACL with Redis: https://github.com/emqtt/emqttd_plugin_redis -Configure emqttd_plugin_redis/etc/plugin.config ------------------------------------------------ +Configure Redis Auth/ACL Plugin +------------------------------- + +etc/plugins/emqttd_auth_redis.conf: .. code-block:: erlang - [ - {emqttd_plugin_redis, [ + {redis_pool, [ + %% pool options + {pool_size, 8}, + {auto_reconnect, 2}, - {eredis_pool, [ - %% ecpool options - {pool_size, 8}, - {auto_reconnect, 2}, + %% redis options + {host, "127.0.0.1"}, + {port, 6379}, + {database, 0}, + {password, ""} + ]}. - %% eredis options - {host, "127.0.0.1"}, - {port, 6379}, - {database, 0}, - {password, ""} - ]}, + %% Variables: %u = username, %c = clientid - %% Variables: %u = username, %c = clientid + %% HMGET mqtt_user:%u is_superuser + {supercmd, ["HGET", "mqtt_user:%u", "is_superuser"]}. - %% HMGET mqtt_user:%u is_superuser - {supercmd, ["HGET", "mqtt_user:%u", "is_superuser"]}, + %% HMGET mqtt_user:%u password + {authcmd, ["HGET", "mqtt_user:%u", "password"]}. - %% HMGET mqtt_user:%u password - {authcmd, ["HGET", "mqtt_user:%u", "password"]}, + %% Password hash algorithm: plain, md5, sha, sha256, pbkdf2? + {password_hash, sha256}. - %% Password hash algorithm: plain, md5, sha, sha256, pbkdf2? - {password_hash, sha256}, + %% SMEMBERS mqtt_acl:%u + {aclcmd, ["SMEMBERS", "mqtt_acl:%u"]}. - %% SMEMBERS mqtt_acl:%u - {aclcmd, ["SMEMBERS", "mqtt_acl:%u"]}, + %% If no rules matched, return... + {acl_nomatch, deny}. - %% If no rules matched, return... - {acl_nomatch, deny}, + %% Load Subscriptions form Redis when client connected. + {subcmd, ["HGETALL", "mqtt_subs:%u"]}. - %% Load Subscriptions form Redis when client connected. - {subcmd, ["HGETALL", "mqtt_subs:%u"]} - ]} - ]. -User HASH ---------- +Redis User HASH +--------------- Set a 'user' hash with 'password' field, for example:: HSET mqtt_user: is_superuser 1 HSET mqtt_user: password "passwd" -ACL Rule SET ------------- +Redis ACL Rule SET +------------------ The plugin uses a redis SET to store ACL rules:: @@ -444,8 +451,8 @@ The plugin uses a redis SET to store ACL rules:: SADD mqtt_acl: "subscribe topic2" SADD mqtt_acl: "pubsub topic3" -Subscription HASH ------------------ +Redis Subscription HASH +----------------------- The plugin can store static subscriptions in a redis Hash:: @@ -453,12 +460,12 @@ The plugin can store static subscriptions in a redis Hash:: HSET mqtt_subs: topic2 1 HSET mqtt_subs: topic3 2 -Load emqttd_plugin_redis Plugin -------------------------------- +Load Redis Auth/ACL Plugin +-------------------------- .. code-block:: bash - ./bin/emqttd_ctl plugins load emqttd_plugin_redis + ./bin/emqttd_ctl plugins load emqttd_auth_redis --------------------------------------------- emqttd_plugin_mongo - MongoDB Auth/ACL Plugin @@ -466,55 +473,51 @@ emqttd_plugin_mongo - MongoDB Auth/ACL Plugin MQTT Authentication, ACL with MongoDB: https://github.com/emqtt/emqttd_plugin_mongo -Configure emqttd_plugin_mongo/etc/plugin.config ------------------------------------------------ +Configure MongoDB Auth/ACL Plugin +--------------------------------- + +etc/plugins/emqttd_plugin_mongo.conf: .. code-block:: erlang - [ - {emqttd_plugin_mongo, [ + {mongo_pool, [ + {pool_size, 8}, + {auto_reconnect, 3}, - {mongo_pool, [ - {pool_size, 8}, - {auto_reconnect, 3}, + %% Mongodb Opts + {host, "localhost"}, + {port, 27017}, + %% {login, ""}, + %% {password, ""}, + {database, "mqtt"} + ]}. - %% Mongodb Driver Opts - {host, "localhost"}, - {port, 27017}, - %% {login, ""}, - %% {password, ""}, - {database, "mqtt"} - ]}, + %% Variables: %u = username, %c = clientid - %% Variables: %u = username, %c = clientid + %% Superuser Query + {superquery, pool, [ + {collection, "mqtt_user"}, + {super_field, "is_superuser"}, + {selector, {"username", "%u"}} + ]}. - %% Superuser Query - {superquery, [ - {collection, "mqtt_user"}, - {super_field, "is_superuser"}, - {selector, {"username", "%u"}} - ]}, + %% Authentication Query + {authquery, pool, [ + {collection, "mqtt_user"}, + {password_field, "password"}, + %% Hash Algorithm: plain, md5, sha, sha256, pbkdf2? + {password_hash, sha256}, + {selector, {"username", "%u"}} + ]}. - %% Authentication Query - {authquery, [ - {collection, "mqtt_user"}, - {password_field, "password"}, - %% Hash Algorithm: plain, md5, sha, sha256, pbkdf2? - {password_hash, sha256}, - {selector, {"username", "%u"}} - ]}, + %% ACL Query: "%u" = username, "%c" = clientid + {aclquery, pool, [ + {collection, "mqtt_acl"}, + {selector, {"username", "%u"}} + ]}. - %% ACL Query: "%u" = username, "%c" = clientid - {aclquery, [ - {collection, "mqtt_acl"}, - {selector, {"username", "%u"}} - ]}, - - %% If no ACL rules matched, return... - {acl_nomatch, deny} - - ]} - ]. + %% If no ACL rules matched, return... + {acl_nomatch, deny}. MongoDB Database ---------------- @@ -526,8 +529,8 @@ MongoDB Database db.createCollection("mqtt_acl") db.mqtt_user.ensureIndex({"username":1}) -User Collection ---------------- +MongoDB User Collection +----------------------- .. code-block:: json @@ -543,8 +546,8 @@ For example:: db.mqtt_user.insert({username: "test", password: "password hash", is_superuser: false}) db.mqtt_user:insert({username: "root", is_superuser: true}) -ACL Collection --------------- +MongoDB ACL Collection +---------------------- .. code-block:: json @@ -561,12 +564,34 @@ For example:: db.mqtt_acl.insert({username: "test", publish: ["t/1", "t/2"], subscribe: ["user/%u", "client/%c"]}) db.mqtt_acl.insert({username: "admin", pubsub: ["#"]}) -Load emqttd_plugin_mongo Plugin -------------------------------- +Load MongoDB Auth/ACL Plugin +---------------------------- .. code-block:: bash - ./bin/emqttd_ctl plugins load emqttd_plugin_mongo + ./bin/emqttd_ctl plugins load emqttd_auth_mongo + +--------------------------- +emqttd_sn: MQTT-SN Protocol +-------------------------- + +MQTT-SN Protocol/Gateway Plugin. + +Configure MQTT-SN Plugin +------------------------- + +.. NOTE:: UDP Port for MQTT-SN: 1884 + +etc/plugins/emqttd_sn.conf:: + + {listener, {1884, []}}. + +Load MQTT-SN Plugin +------------------- + +.. code:: + + ./bin/emqttd_ctl plugins load emqttd_sn ----------------------------- emqttd_stomp - STOMP Protocol @@ -574,48 +599,41 @@ emqttd_stomp - STOMP Protocol Support STOMP 1.0/1.1/1.2 clients to connect to emqttd broker and communicate with MQTT Clients. -Configure emqttd_stomp/etc/plugin.config ----------------------------------------- +Configure Stomp Plugin +---------------------- + +etc/plugins/emqttd_stomp.conf: .. NOTE:: Default Port for STOMP Protocol: 61613 .. code-block:: erlang - [ - {emqttd_stomp, [ + {default_user, [ + {login, "guest"}, + {passcode, "guest"} + ]}. - {default_user, [ - {login, "guest"}, - {passcode, "guest"} - ]}, + {allow_anonymous, true}. - {allow_anonymous, true}, + {frame, [ + {max_headers, 10}, + {max_header_length, 1024}, + {max_body_length, 8192} + ]}. - %%TODO: unused... - {frame, [ - {max_headers, 10}, - {max_header_length, 1024}, - {max_body_length, 8192} - ]}, + {listener, emqttd_stomp, 61613, [ + {acceptors, 4}, + {max_clients, 512} + ]}. - {listeners, [ - {emqttd_stomp, 61613, [ - {acceptors, 4}, - {max_clients, 512} - ]} - ]} - ]} - ]. - -Load emqttd_stomp Plugin ------------------------- +Load Stomp Plugin +----------------- .. code-block:: bash ./bin/emqttd_ctl plugins load emqttd_stomp - ----------------------------------- emqttd_sockjs - STOMP/SockJS Plugin ----------------------------------- @@ -629,18 +647,21 @@ Configure emqttd_sockjs .. code-block:: erlang - [ - {emqttd_sockjs, [ + {sockjs, []}. - {sockjs, []}, - - {cowboy_listener, {stomp_sockjs, 61616, 4}}, + {cowboy_listener, {stomp_sockjs, 61616, 4}}. + %% TODO: unused... + {stomp, [ + {frame, [ + {max_headers, 10}, + {max_header_length, 1024}, + {max_body_length, 8192} ]} - ]. + ]}. -Load emqttd_sockjs Plugin -------------------------- +Load SockJS Plugin +------------------ .. NOTE:: emqttd_stomp Plugin required. @@ -661,8 +682,8 @@ emqttd_recon - Recon Plugin The plugin loads `recon`_ library on a running emqttd broker. Recon libray helps debug and optimize an Erlang application. -Load emqttd_recon Plugin ------------------------- +Load Recon Plugin +----------------- .. code-block:: bash @@ -689,8 +710,8 @@ Erlang Module Reloader for Development .. NOTE:: Don't load the plugin in production! -Load emqttd_reloader Plugin ---------------------------- +Load 'Reloader' Plugin +---------------------- .. code-block:: bash @@ -712,15 +733,22 @@ Plugin Development Guide Create a Plugin Project ----------------------- -Clone emqttd source from github.com:: +Clone emqttd_plugin_template source from github.com:: - git clone https://github.com/emqtt/emqttd.git + git clone https://github.com/emqtt/emqttd_plugin_template.git -Create a plugin project under 'plugins' folder:: +Create a plugin project with erlang.mk and depends on 'emqttd' application, the 'Makefile':: - cd plugins && mkdir emqttd_my_plugin + PROJECT = emqttd_plugin_abc + PROJECT_DESCRIPTION = emqttd abc plugin + PROJECT_VERSION = 1.0 - cd emqttd_my_plugin && rebar create-app appid=emqttd_my_plugin + DEPS = emqttd + dep_emqttd = git https://github.com/emqtt/emqttd emq20 + + COVER = true + + include erlang.mk Template Plugin: https://github.com/emqtt/emqttd_plugin_template @@ -735,7 +763,7 @@ emqttd_auth_demo.erl - demo authentication module: -behaviour(emqttd_auth_mod). - -include("../../../include/emqttd.hrl"). + -include_lib("emqttd/include/emqttd.hrl"). -export([init/1, check/3, description/0]). @@ -754,7 +782,7 @@ emqttd_acl_demo.erl - demo ACL module: -module(emqttd_acl_demo). - -include("../../../include/emqttd.hrl"). + -include_lib("emqttd/include/emqttd.hrl"). %% ACL callbacks -export([init/1, check_acl/2, reload_acl/1, description/0]). @@ -830,7 +858,7 @@ emqttd_cli_demo.erl: -module(emqttd_cli_demo). - -include("../../../include/emqttd_cli.hrl"). + -include_lib("emqttd/include/emqttd_cli.hrl"). -export([cmd/1]). @@ -850,13 +878,14 @@ There will be a new CLI after the plugin loaded:: ./bin/emqttd_ctl cmd arg1 arg2 - .. _emqttd_dashboard: https://github.com/emqtt/emqttd_dashboard +.. _emqttd_auth_ldap: https://github.com/emqtt/emqttd_auth_ldap .. _emqttd_auth_http: https://github.com/emqtt/emqttd_auth_http -.. _emqttd_plugin_mysql: https://github.com/emqtt/emqttd_plugin_mysql -.. _emqttd_plugin_pgsql: https://github.com/emqtt/emqttd_plugin_pgsql -.. _emqttd_plugin_redis: https://github.com/emqtt/emqttd_plugin_redis -.. _emqttd_plugin_mongo: https://github.com/emqtt/emqttd_plugin_mongo +.. _emqttd_auth_mysql: https://github.com/emqtt/emqttd_plugin_mysql +.. _emqttd_auth_pgsql: https://github.com/emqtt/emqttd_plugin_pgsql +.. _emqttd_auth_redis: https://github.com/emqtt/emqttd_plugin_redis +.. _emqttd_auth_mongo: https://github.com/emqtt/emqttd_plugin_mongo +.. _emqttd_sn: https://github.com/emqtt/emqttd_sn .. _emqttd_stomp: https://github.com/emqtt/emqttd_stomp .. _emqttd_sockjs: https://github.com/emqtt/emqttd_sockjs .. _emqttd_recon: https://github.com/emqtt/emqttd_recon