introduction.md 3.9 KB

简介

emqx-extension-hook 插件用于提供钩子(Hook)的多语言支持。它能够允许其他的语言,例如:Python,Java 等,能够直接表达如何挂载钩子,和处理相应的钩子事件。

该插件给 EMQ X 带来的扩展性十分的强大,甚至于所有基于钩子的插件都可以通过其他编程语言实现。唯一不同的是在性能上肯定有一定的降低。

目前,一些常见的场景有:

  • 通过 client.authenticate 钩子,使用其他编程语言查询数据库,判断该客户端是否具有接入的权限。
  • 通过 client.check_acl 钩子,使用其他编程语言查询数据库,实现发布/订阅的权限控制逻辑。
  • 通过 message 类的钩子,实现消息收发的控制和数据格式转换。
  • 获取客户端所有的事件,将其存储进三方的日志、或数据平台中。

声明:当前仅实现了 Python、Java 的支持

声明:message 类钩子功能仅包含在企业版当中

要求

EMQ X 发行包中不包含其他语言的运行环境。它要求:

  • 宿主机需包含其他编程语言对应的执行环境。
  • 必须将源码(或编译后的代码)、资源文件等,放到 emqx-extension-hook 指示的路径。
  • 代码的实现,若包含三方依赖、库等,它应该包含在 emqx-extension-hook 对其的搜索路径中。

架构

emqx-extension-hook 是 EMQ X 的一个插件,它主要包括:

  1. 驱动的管理。例如:如何启动/停止某个驱动。
  2. 事件的分发。例如:根据各个驱动所注册的钩子列表的不同,向各个驱动分发事件,传递返回值等。
  3. 预置了驱动的实现。包括 Python 和 Java 驱动的实现,和方便用户集成开发的 SDK 代码包。

其架构图如下:

 EMQ X                                      Third-party Runtimes
+========================+                 +====================+
|    Extension           |                 |                    |
|   +----------------+   |     Hooks       |  Python scripts /  |
|   |    Drivers     | ------------------> |  Java Classes   /  |
|   +----------------+   |     (pipe)      |  Others ...        |
|                        |                 |                    |
+========================+                 +====================+

图中表明,由 Client 产生的所有的事件,例如:连接、发布、订阅等,都会由 emqx-extension-hook插件分发给下面的各个 驱动(Driver);而,驱动则负责如何与三方运行时的进行通信。

广义上的驱动(Driver)可以分为两类:

  1. 编程语言类。
  2. 服务类。例如:HTTP 就属于此类。

emqx-extension-hook 并不关心驱动实际的类型和实现,只要其实现了对应的接口即可。

驱动

本文中,只有未经限定说明的驱动,都是指编程语言类的驱动。

编程语言类驱动是基于 Erlang - Port 进行实现。它本质上是由 emqx-extension-hook 是启动一个其他语言的程序,并使用管道(Pipe)实现两个进程间的通信。

此类驱动的实现包括两部分的内容:

  1. Erlang 侧的实现,它包含如何启动其他语言的运行时系统、和分发请求、处理结果等。
  2. 其他语言侧的实现。它包含如何和 Erlang 虚拟机通信,如何执行函数调用等。

如:

    Erlang VM                       Third Runtimes (e.g: Java VM)
   +===========+=========+         +=========+================+
   | Extension | Driver  | <=====> |  Driver | User's Codes   |
   +===========+=========+         +=========+================+

而,对于基于服务的驱动,原理就很简单了。以 HTTP 为例,它的实现仅需要一个 HTTP 客户端、和指定服务端返回的数据格式即可。

集成与调试

参见 SDK 规范、和对应语言的开发手册