EMQ X R3.2 插件开发
创建插件项目
参考 emqx_plugin_template (opens new window) 插件模版创建新的插件项目。
Tip
在 \<plugin name>_app.erl
文件中必须加上标签 -emqx_plugin(\<type>).
以表明这是一个<type> 类型的插件。目前支持的枚举值有: auth | backend | bridge | ?MODULE
创建认证/访问控制模块
认证演示模块 - emqx_auth_demo.erl
-module(emqx_auth_demo).
-export([ init/1
, check/2
, description/0
]).
init(Opts) -> {ok, Opts}.
check(_Credentials = #{client_id := ClientId, username := Username, password := Password}, _State) ->
io:format("Auth Demo: clientId=~p, username=~p, password=~p~n", [ClientId, Username, Password]),
ok.
description() -> "Auth Demo Module".
访问控制演示模块 - emqx_acl_demo.erl
-module(emqx_acl_demo).
-include_lib("emqx/include/emqx.hrl").
%% ACL callbacks
-export([ init/1
, check_acl/5
, reload_acl/1
, description/0
]).
init(Opts) ->
{ok, Opts}.
check_acl({Credentials, PubSub, _NoMatchAction, Topic}, _State) ->
io:format("ACL Demo: ~p ~p ~p~n", [Credentials, PubSub, Topic]),
allow.
reload_acl(_State) ->
ok.
description() -> "ACL Demo Module".
注册认证、访问控制模块 - emqx_plugin_template_app.erl
ok = emqx:hook('client.authenticate', fun emqx_auth_demo:check/2, []),
ok = emqx:hook('client.check_acl', fun emqx_acl_demo:check_acl/5, []).
注册钩子(Hooks)
通过钩子(Hook)处理客户端上下线、主题订阅、消息收发。
emqx_plugin_template.erl:
%% Called when the plugin application start
load(Env) ->
emqx:hook('client.authenticate', fun ?MODULE:on_client_authenticate/2, [Env]),
emqx:hook('client.check_acl', fun ?MODULE:on_client_check_acl/5, [Env]),
emqx:hook('client.connected', fun ?MODULE:on_client_connected/4, [Env]),
emqx:hook('client.disconnected', fun ?MODULE:on_client_disconnected/3, [Env]),
emqx:hook('client.subscribe', fun ?MODULE:on_client_subscribe/3, [Env]),
emqx:hook('client.unsubscribe', fun ?MODULE:on_client_unsubscribe/3, [Env]),
emqx:hook('session.created', fun ?MODULE:on_session_created/3, [Env]),
emqx:hook('session.resumed', fun ?MODULE:on_session_resumed/3, [Env]),
emqx:hook('session.subscribed', fun ?MODULE:on_session_subscribed/4, [Env]),
emqx:hook('session.unsubscribed', fun ?MODULE:on_session_unsubscribed/4, [Env]),
emqx:hook('session.terminated', fun ?MODULE:on_session_terminated/3, [Env]),
emqx:hook('message.publish', fun ?MODULE:on_message_publish/2, [Env]),
emqx:hook('message.deliver', fun ?MODULE:on_message_deliver/3, [Env]),
emqx:hook('message.acked', fun ?MODULE:on_message_acked/3, [Env]),
emqx:hook('message.dropped', fun ?MODULE:on_message_dropped/3, [Env]).
所有可用钩子(Hook)说明:
钩子 | 说明 |
---|---|
client.authenticate | 连接认证 |
client.check_acl | ACL 校验 |
client.connected | 客户端上线 |
client.disconnected | 客户端连接断开 |
client.subscribe | 客户端订阅主题 |
client.unsubscribe | 客户端取消订阅主题 |
session.created | 会话创建 |
session.resumed | 会话恢复 |
session.subscribed | 会话订阅主题后 |
session.unsubscribed | 会话取消订阅主题后 |
session.terminated | 会话终止 |
message.publish | MQTT 消息发布 |
message.deliver | MQTT 消息进行投递 |
message.acked | MQTT 消息回执 |
message.dropped | MQTT 消息丢弃 |
注册 CLI 命令
扩展命令行演示模块 - emqx_cli_demo.erl
-module(emqx_cli_demo).
-export([cmd/1]).
cmd(["arg1", "arg2"]) ->
emqx_cli:print("ok");
cmd(_) ->
emqx_cli:usage([{"cmd arg1 arg2", "cmd demo"}]).
注册命令行模块 - emqx_plugin_template_app.erl
ok = emqx_ctl:register_command(cmd, {emqx_cli_demo, cmd}, []),
插件加载后, ./bin/emqx_ctl
新增命令行:
./bin/emqx_ctl cmd arg1 arg2
插件配置文件
插件自带配置文件放置在 etc/${plugin_name}.conf|config
。EMQ X 支持两种插件配置格式:
Erlang 原生配置文件格式 -
${plugin_name}.config
:[
{plugin_name, [
{key, value}
]}
].
sysctl 的
k = v
通用格式 -${plugin_name}.conf
:plugin_name.key = value
Tip
k = v
格式配置需要插件开发者创建 priv/plugin_name.schema
映射文件。
编译发布插件
解压 emqx-enterprise-rel.zip:
unzip emqx-enterprise-rel.zip
rebar.config 添加依赖:
{deps,
[ {plugin_name, {git, "url_of_plugin", {tag, "tag_of_plugin"}}}
, ....
....
]
}
rebar.config 中 relx 段落添加:
{relx,
[...
, ...
, {release, {emqx, git_describe},
[
{plugin_name, load},
]
}
]
}