EMQ X R3.2 插件开发

创建插件项目

参考 emqx_plugin_template EMQ X R3.2 插件开发 - 图1 (opens new window) 插件模版创建新的插件项目。

Tip

\<plugin name>_app.erl 文件中必须加上标签 -emqx_plugin(\<type>). 以表明这是一个<type> 类型的插件。目前支持的枚举值有: auth | backend | bridge | ?MODULE

创建认证/访问控制模块

认证演示模块 - emqx_auth_demo.erl

  1. -module(emqx_auth_demo).
  2. -export([ init/1
  3. , check/2
  4. , description/0
  5. ]).
  6. init(Opts) -> {ok, Opts}.
  7. check(_Credentials = #{client_id := ClientId, username := Username, password := Password}, _State) ->
  8. io:format("Auth Demo: clientId=~p, username=~p, password=~p~n", [ClientId, Username, Password]),
  9. ok.
  10. description() -> "Auth Demo Module".

访问控制演示模块 - emqx_acl_demo.erl

  1. -module(emqx_acl_demo).
  2. -include_lib("emqx/include/emqx.hrl").
  3. %% ACL callbacks
  4. -export([ init/1
  5. , check_acl/5
  6. , reload_acl/1
  7. , description/0
  8. ]).
  9. init(Opts) ->
  10. {ok, Opts}.
  11. check_acl({Credentials, PubSub, _NoMatchAction, Topic}, _State) ->
  12. io:format("ACL Demo: ~p ~p ~p~n", [Credentials, PubSub, Topic]),
  13. allow.
  14. reload_acl(_State) ->
  15. ok.
  16. description() -> "ACL Demo Module".

注册认证、访问控制模块 - emqx_plugin_template_app.erl

  1. ok = emqx:hook('client.authenticate', fun emqx_auth_demo:check/2, []),
  2. ok = emqx:hook('client.check_acl', fun emqx_acl_demo:check_acl/5, []).

注册钩子(Hooks)

通过钩子(Hook)处理客户端上下线、主题订阅、消息收发。

emqx_plugin_template.erl:

  1. %% Called when the plugin application start
  2. load(Env) ->
  3. emqx:hook('client.authenticate', fun ?MODULE:on_client_authenticate/2, [Env]),
  4. emqx:hook('client.check_acl', fun ?MODULE:on_client_check_acl/5, [Env]),
  5. emqx:hook('client.connected', fun ?MODULE:on_client_connected/4, [Env]),
  6. emqx:hook('client.disconnected', fun ?MODULE:on_client_disconnected/3, [Env]),
  7. emqx:hook('client.subscribe', fun ?MODULE:on_client_subscribe/3, [Env]),
  8. emqx:hook('client.unsubscribe', fun ?MODULE:on_client_unsubscribe/3, [Env]),
  9. emqx:hook('session.created', fun ?MODULE:on_session_created/3, [Env]),
  10. emqx:hook('session.resumed', fun ?MODULE:on_session_resumed/3, [Env]),
  11. emqx:hook('session.subscribed', fun ?MODULE:on_session_subscribed/4, [Env]),
  12. emqx:hook('session.unsubscribed', fun ?MODULE:on_session_unsubscribed/4, [Env]),
  13. emqx:hook('session.terminated', fun ?MODULE:on_session_terminated/3, [Env]),
  14. emqx:hook('message.publish', fun ?MODULE:on_message_publish/2, [Env]),
  15. emqx:hook('message.deliver', fun ?MODULE:on_message_deliver/3, [Env]),
  16. emqx:hook('message.acked', fun ?MODULE:on_message_acked/3, [Env]),
  17. emqx:hook('message.dropped', fun ?MODULE:on_message_dropped/3, [Env]).

所有可用钩子(Hook)说明:

钩子说明
client.authenticate连接认证
client.check_aclACL 校验
client.connected客户端上线
client.disconnected客户端连接断开
client.subscribe客户端订阅主题
client.unsubscribe客户端取消订阅主题
session.created会话创建
session.resumed会话恢复
session.subscribed会话订阅主题后
session.unsubscribed会话取消订阅主题后
session.terminated会话终止
message.publishMQTT 消息发布
message.deliverMQTT 消息进行投递
message.ackedMQTT 消息回执
message.droppedMQTT 消息丢弃

注册 CLI 命令

扩展命令行演示模块 - emqx_cli_demo.erl

  1. -module(emqx_cli_demo).
  2. -export([cmd/1]).
  3. cmd(["arg1", "arg2"]) ->
  4. emqx_cli:print("ok");
  5. cmd(_) ->
  6. emqx_cli:usage([{"cmd arg1 arg2", "cmd demo"}]).

注册命令行模块 - emqx_plugin_template_app.erl

  1. ok = emqx_ctl:register_command(cmd, {emqx_cli_demo, cmd}, []),

插件加载后, ./bin/emqx_ctl 新增命令行:

  1. ./bin/emqx_ctl cmd arg1 arg2

插件配置文件

插件自带配置文件放置在 etc/${plugin_name}.conf|config 。EMQ X 支持两种插件配置格式:

  1. Erlang 原生配置文件格式 - ${plugin_name}.config :

    1. [
    2. {plugin_name, [
    3. {key, value}
    4. ]}
    5. ].
  2. sysctl 的 k = v 通用格式 - ${plugin_name}.conf :

    1. plugin_name.key = value

Tip

k = v 格式配置需要插件开发者创建 priv/plugin_name.schema 映射文件。

编译发布插件

  1. 解压 emqx-enterprise-rel.zip:

    1. unzip emqx-enterprise-rel.zip
  2. rebar.config 添加依赖:

    1. {deps,
    2. [ {plugin_name, {git, "url_of_plugin", {tag, "tag_of_plugin"}}}
    3. , ....
    4. ....
    5. ]
    6. }
  3. rebar.config 中 relx 段落添加:

    1. {relx,
    2. [...
    3. , ...
    4. , {release, {emqx, git_describe},
    5. [
    6. {plugin_name, load},
    7. ]
    8. }
    9. ]
    10. }