运用 Python 研发 EMQ X 插件
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">从 v4.1 版本<span style="color: black;">起始</span>,EMQ X <span style="color: black;">供给</span>了专门的多语言支持插件 </span><span style="color: black;">(</span><span style="color: black;">emqx_extension_hook(https://github.com/emqx/emqx-extension-hook)</span> <span style="color: black;">,现已支持<span style="color: black;">运用</span>其他编程语言来处理 EMQ X 中的钩子事件,<span style="color: black;">研发</span>者<span style="color: black;">能够</span><span style="color: black;">运用</span> Python <span style="color: black;">或</span> Java 快速<span style="color: black;">研发</span>自己的插件,在官方功能的<span style="color: black;">基本</span>上进行扩展,满足自己的业务场景。例如:</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">验证某客户端的登录权限:客户端连接时触发对应函数,<span style="color: black;">经过</span>参数获取客户端信息后<span style="color: black;">经过</span>读取数据库、比对等操作判定<span style="color: black;">是不是</span>有登录权限</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">记录客户端在线状态与上下线历史:客户端状态变动时触发对应函数,<span style="color: black;">经过</span>参数获取客户端信息,改写数据库中客户端在线状态</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">校验某客户端的 PUB/SUB 的操作权限:发布/订阅时触发对应函数,<span style="color: black;">经过</span>参数获取客户端信息与当前主题,判定客户端<span style="color: black;">是不是</span>有对应的操作权限</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">处理会话 (Sessions) 和 <span style="color: black;">信息</span> (Message) 事件,实现订阅关系与<span style="color: black;">信息</span>处理/存储:<span style="color: black;">信息</span>发布、状态变动时触发对应函数,获取当前客户端信息、<span style="color: black;">信息</span>状态与消息内容,转发到 Kafka 或数据库进行存储。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">注:<span style="color: black;">信息</span>(Message) 类钩子,仅在企业版中支持。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">Python 和 Java 驱动基于 Erlang/OTP-Port</span><span style="color: black;"> (https://erlang.org/doc/tutorial/c_port.html)</span><span style="color: black;">进程间通信实现,本身<span style="color: black;">拥有</span>非常高的吞吐性能,本文以 Python 拓展为例介绍 EMQ X 跨语言拓展<span style="color: black;">运用</span>方式。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><img src="https://mmbiz.qpic.cn/mmbiz_jpg/u21HUF7OcgBZk4q1WeCLlKGbYyqjicOZyLBotzb7iaWUgxSkYscJib9x5KQ44xeIXcoyZsRlfW1J6Wvla6QVC0JuA/640?wx_fmt=jpeg&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;"></span></p><strong style="color: blue;"><span style="color: black;">Python 拓展<span style="color: black;">运用</span>示例</span></strong>
<h3 style="color: black; text-align: left; margin-bottom: 10px;"><span style="color: black;"><span style="color: black;">需求</span></span></h3>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">EMQ X 所在服务器需安装 Python 3.6 以上版本</span></p>
<h3 style="color: black; text-align: left; margin-bottom: 10px;"><span style="color: black;"><span style="color: black;">运用</span><span style="color: black;">过程</span></span></h3>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">经过</span> pip 安装 Python SDK</span><span style="color: black;"> (https://pypi.org/project/emqx-extension-sdk/)</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">调整 EMQ X 配置,<span style="color: black;">保证</span><span style="color: black;">关联</span>配置项正确指向 Python 项目</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">引入 SDK 编写代码</span></p>
<h3 style="color: black; text-align: left; margin-bottom: 10px;"><span style="color: black;">安装</span></h3>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">经过</span> pip 命令在本地安装 SDK,<strong style="color: blue;"><span style="color: black;">保证</span><span style="color: black;">运用</span> pip3 进行安装</strong>:</span></p><span style="color: black;"><span style="color: black;">pip3</span> install emqx-extension-sdk</span>
<h3 style="color: black; text-align: left; margin-bottom: 10px;"><span style="color: black;">修改配置</span></h3>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">修改 emqx-extension-hook 插件配置,正确<span style="color: black;">运用</span>拓展:</span></p><span style="color: black;"><span style="color: black;">#</span><span style="color: black;"># Setup the supported drivers</span></span><span style="color: black;"><span style="color: black;">#</span><span style="color: black;">#</span></span><span style="color: black;"><span style="color: black;">#</span><span style="color: black;"># Value: python2 | python3 | java</span></span><span style="color: black;">exhook.drivers = python3</span><span style="color: black;"><span style="color: black;">#</span><span style="color: black;"># Search path for scripts/library</span></span><span style="color: black;">exhook.drivers.python3.path = data/extension/hooks.py</span><span style="color: black;"><span style="color: black;">#</span><span style="color: black;"># Call timeout</span></span><span style="color: black;"><span style="color: black;">#</span><span style="color: black;">#</span></span><span style="color: black;"><span style="color: black;">#</span><span style="color: black;"># Value: Duration</span></span><span style="color: black;"><span style="color: black;">#</span><span style="color: black;">#exhook.drivers.python3.call_timeout = 5s</span></span><span style="color: black;"><span style="color: black;">#</span><span style="color: black;"># Initial module name</span></span><span style="color: black;"><span style="color: black;">#</span><span style="color: black;"># Your filename or module name</span></span><span style="color: black;">exhook.drivers.python3.init_module = hooks</span>
<h3 style="color: black; text-align: left; margin-bottom: 10px;"><span style="color: black;">编写代码</span></h3>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">在 emqx/data/extension 目录下新建 hooks.py 文件,引入 SDK 编写业务<span style="color: black;">规律</span>,示例程序如下:</span></p><span style="color: black;"><span style="color: black;">## data/extension/hooks.py</span></span><span style="color: black;"><span style="color: black;">from</span>emqx_extension.hooks<span style="color: black;">import</span> EmqxHookSdk, hooks_handler</span><span style="color: black;"><span style="color: black;">from</span> emqx_extension.types <span style="color: black;">import</span> EMQX_CLIENTINFO_PARSE_T, EMQX_MESSAGE_PARSE_T</span><span style="color: black;"><span style="color: black;"># 继承 SDK HookSdk 类</span></span><span style="color: black;"><span style="color: black;"><span style="color: black;">class</span> <span style="color: black;">CustomHook</span><span style="color: black;">(EmqxHookSdk)</span>:</span></span><span style="color: black;"> <span style="color: black;"># <span style="color: black;">运用</span>装饰器注册 hooks</span></span><span style="color: black;"><span style="color: black;"> @hooks_handler()</span></span><span style="color: black;"> <span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">on_client_connect</span><span style="color: black;">(self,</span></span></span><span style="color: black;"> conninfo: EMQX_CLIENTINFO_PARSE_T = None,</span><span style="color: black;"> props: dict = None,</span><span style="color: black;"><span style="color: black;">state: list = None)</span>:</span><span style="color: black;"> print(<span style="color: black;">f <span style="color: black;">{conninfo.clientid}</span> connecte</span>)</span><span style="color: black;"><span style="color: black;"> @hooks_handler()</span></span><span style="color: black;"> <span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">on_client_connected</span><span style="color: black;">(self,</span></span></span><span style="color: black;">clientinfo: EMQX_CLIENTINFO_PARSE_T,</span><span style="color: black;"><span style="color: black;"> state: list = None)</span>:</span><span style="color: black;"> print(</span><span style="color: black;"> <span style="color: black;">f <span style="color: black;">{clientinfo.clientid}</span> connected</span>)</span><span style="color: black;"><span style="color: black;"> @hooks_handler()</span></span><span style="color: black;"> <span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">on_client_check_acl</span><span style="color: black;">(self, clientinfo: EMQX_CLIENTINFO_PARSE_T,</span></span></span><span style="color: black;"> pubsub: str,</span><span style="color: black;"> topic: str,</span><span style="color: black;"> result: bool,</span><span style="color: black;"><span style="color: black;"> state: tuple)</span> -> bool:</span><span style="color: black;"> print(</span><span style="color: black;"> <span style="color: black;">f <span style="color: black;">{clientinfo.username}</span>check ACL:<span style="color: black;">{pubsub}</span> <span style="color: black;">{topic}</span></span>)</span><span style="color: black;"> <span style="color: black;"># 用户名为空时,ACL 验证不<span style="color: black;">经过</span></span></span><span style="color: black;"> <span style="color: black;">if</span> clientinfo.username == :</span><span style="color: black;"> <span style="color: black;">return</span> <span style="color: black;">False</span></span><span style="color: black;"> <span style="color: black;">return</span> <span style="color: black;">True</span></span><span style="color: black;"><span style="color: black;"> @hooks_handler()</span></span><span style="color: black;"> <span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">on_client_authenticate</span><span style="color: black;">(self, clientinfo: EMQX_CLIENTINFO_PARSE_T, authresult,</span></span></span><span style="color: black;"><span style="color: black;"> state)</span> -> bool:</span><span style="color: black;"> print(</span><span style="color: black;"> <span style="color: black;">f <span style="color: black;">{clientinfo.clientid}</span> authenticate</span>)</span><span style="color: black;"> <span style="color: black;"># clientid 不为空时,验证<span style="color: black;">经过</span></span></span><span style="color: black;"> <span style="color: black;">if</span>clientinfo.clientid != :</span><span style="color: black;"> <span style="color: black;">return</span> <span style="color: black;">True</span></span><span style="color: black;"> <span style="color: black;">return</span> <span style="color: black;">False</span></span><span style="color: black;"> <span style="color: black;"># on_message_* 仅支持企业版</span></span><span style="color: black;"><span style="color: black;"> @hooks_handler()</span></span><span style="color: black;"> <span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">on_message_publish</span><span style="color: black;">(self, message: EMQX_MESSAGE_PARSE_T, state)</span>:</span></span><span style="color: black;"> print(</span><span style="color: black;"> <span style="color: black;">f <span style="color: black;">{message.topic}</span> <span style="color: black;">{message.payload}</span></span>)</span><span style="color: black;">emqx_hook = CustomHook(hook_module=<span style="color: black;">f<span style="color: black;">{__name__}</span>.emqx_hook</span>)</span><span style="color: black;"><span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">init</span><span style="color: black;">()</span>:</span></span><span style="color: black;"> <span style="color: black;">return</span>emqx_hook.start()</span><span style="color: black;"><span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">deinit</span><span style="color: black;">()</span>:</span></span><span style="color: black;"> <span style="color: black;">return</span></span>
<h3 style="color: black; text-align: left; margin-bottom: 10px;"><span style="color: black;"> <span style="color: black;">起步</span></span></h3>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">起步</span> emqx_extension_hook 插件,<span style="color: black;">倘若</span>配置错误或代码编写错误将<span style="color: black;">没法</span>正常<span style="color: black;">起步</span>。<span style="color: black;">起步</span>后尝试<span style="color: black;">创立</span> MQTT 连接并观察业务运行<span style="color: black;">状况</span>。</span></p><span style="color: black;">./bin/emqx_ctl plugins <span style="color: black;">load</span> emqx_extension_hook</span> <strong style="color: blue;"><span style="color: black;">进阶<span style="color: black;">研发</span> </span></strong> <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">日前</span> EMQ X Python 拓展 SDK 是开源的,<span style="color: black;">倘若</span>对可控性、性能<span style="color: black;">需求</span>更高,或需要<span style="color: black;">运用</span> Python 2.7 版本的运行环境,欢迎贡献代码或基于原始示例进行<span style="color: black;">研发</span>:</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">代码仓库:emqx-extension-python-sdk </span><span style="color: black;">(https://github.com/emqx/emqx-extension-python-sdk)</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">Python 原始示例,可<span style="color: black;">运用</span>该示例<span style="color: black;">自动</span>封装:emqx-extension-hook main.py </span><span style="color: black;">(https://github.com/emqx/emqx-extension-hook/blob/master/test/scripts/main.py)</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="https://mmbiz.qpic.cn/mmbiz_png/u21HUF7OcgDYPH7Y6QeGICicLR2R5Y4BCgAyzR7YaR0aSMa0sTKWnju1RWJHKhjqCBZEvARJxpY2tqN5aW5YzCw/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">点击"阅读原文" ,<span style="color: black;">认识</span><span style="color: black;">更加多</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">↓↓↓</p>
你的话语真是温暖如春,让我心生感激。 外链发布论坛学习网络优化SEO。 感谢您的精彩评论,为我带来了新的思考角度。 软文发布论坛开幕式圆满成功。 http://www.fok120.com
页:
[1]