需求

  1. 在EMQ中添加认证插件,将到来的MQTT连接的ClientID、UserName、Password通过HTTP协议发送到认证服务器,用返回的数据决定是否允许该连接;
  2. 在连接时和断开时向服务器发送设备上线和离线信息,以支持设备管理的需要。

目前进度

3.12 基本已经掌握了插件开发的模式,但是目前发现也许可以组合几个已有的插件实现我们的需求,如果不用自己编码,虽然配置麻烦一点,但是还是能省下大量时间,初步设想是mysql认证/访问控制插件(主要采用访问控制功能)+http认证插件(加密算法认证)+webhook插件(上下线通知)

已有插件

EMQ中有一个使用http的认证插件,但使用它必须指定superuser认证服务器和访问权限服务器,不能单独开启普通用户认证功能,另外还需要集成上下线通知,我们只用到了他的三分之一功能,并且还需要额外功能,可以考虑的方案有两个,一是改写这个插件,禁用其他功能,并加上通知功能,另一个方案是自己写一个。

方案一的优点是插件部署方便,可以直接借原插件的壳,而不需要重新发布emq的整个release,缺点是代码修改很费时间,也不一定能切割出所有功能。

方案二的优点是编码简单,缺点是需要重新打包整个镜像。主要的挑战在于快速打包发布镜像。

实现路线

  1. 了解erlang基本语法,完成helloworld
  2. 编译运行EMQ的插件模板,尝试简单的修改
  3. 学习使用erlang的http库
  4. 在插件中加入http请求代码
  5. 完成简单的全流程
  6. 加入上下线hook
  7. 完成插件的config配置
  8. 整理代码,打包成独立插件并发布源码

Erlang helloworld

在erlang的官网上有一个quick start教程,半天时间基本可以看完所有关于erlang的基础语法,erlang跟golang很像,特别是并发部分,但是编写风格跟C/C++/JAVA系离得比较远,而golang则更靠近,更让我感到亲切。

EMQ插件模板

目前EMQ的插件都以独立仓库的形式开源,因此不需要clone整个emq项目,只需要clone一个插件模板就可以创建插件,而且直接在目录下make即可编译,如果增加库需要学习一下erlang库的链接配置方法。

模板里的代码已经加载了所有钩子(hook),并且在每一个钩子处打印提示信息,插入代码非常方便。

%% Called when the plugin application start
load(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.delivered', fun ?MODULE:on_message_delivered/3, [Env]),
emqx:hook('message.acked', fun ?MODULE:on_message_acked/3, [Env]),
emqx:hook('message.dropped', fun ?MODULE:on_message_dropped/3, [Env]),

另外在acl(访问控制)的demo里有check函数,在收到连接时检查ClientID、UserName和Password,这里正是我所要的钩子,只需要在这里插入一个http的请求,通过response来判断是否允许连接就可以了。

我在插入http客户端代码的时候遇到了一个小问题:

我在init函数中增加了inets:start(),这是httpc说明中所说的初始化步骤,但是在加入这一步初始化后的http请求会发生错误,而不加入这个函数反而能正常获得response,因此我推测是emq本身早已执行了这一步初始化,因此不应当再次执行初始化。详细的原因我目前就不找了(能用就行)

后续:后面一直报相同的错,学习了一下erlang的报错机制后才发现错的是io:format()语句的参数格式,而不是因为inets:start(),以后还是要注意细节,这么小的一个问题浪费了我一整天的时间来调试,非常不值得。

Erlang HTTP client

Erlang作为爱立信为电信产业设计的语言,在网络方面的库非常发达,http是其标准库的一部分,这里是官方的使用说明

完成简单的全流程

在解决掉上述的小小问题之后,我成功在连接接入过程中插入了向外界发送http请求的接口。

插件配置

除了代码以外,还需要将整个插件单独整理出来,并且加入简单的配置功能,否则参数直接进代码会带来很大的麻烦。

emq的配置管理用了一个叫clique的库,文档少,官方库里只有readme里一个示例,很难搞清楚用法。

EMQ插件通过HTTP连接认证服务器实现认证的更多相关文章

  1. Spring Cloud实战 | 第九篇:Spring Cloud整合Spring Security OAuth2认证服务器统一认证自定义异常处理

    本文完整代码下载点击 一. 前言 相信了解过我或者看过我之前的系列文章应该多少知道点我写这些文章包括创建 有来商城youlai-mall 这个项目的目的,想给那些真的想提升自己或者迷茫的人(包括自己- ...

  2. EMQ插件组合实现物联网边缘平台的设备通信管理

    上一篇随笔我简单的记录了我对EMQ插件开发的了解过程,最后发现还是可以组合复用已有插件,因此这篇随笔用于记录使用的情况以及是否达到预期. 首先测试mysql认证插件的使用方式: emqx_auth_m ...

  3. freeradius整合AD域作anyconncet认证服务器

    一.服务器要求 Radius服务器:centos6.6.hostname.selinux  disabled.stop iptables AD域服务器:Windows Server 2008 R2 E ...

  4. Strophe.js连接XMPP服务器Openfire、Tigase实现Web私聊、群聊(MUC)

    XMPP(Extensible Messaging and Presence Protocol)是一种网络即时通讯协议,它基于XML,具有很强的扩展性,被广泛使用在即时通讯软件.网络游戏聊天.Web聊 ...

  5. SSH如何通过公钥连接云服务器

    导读 通常我们连接远程服务器(linux)windows下通过putty或xshell等工具远程连接.linux下可以直接通过ssh命令连接.其实这两者都是一致的,都是通过ssh协议进行传输. 如果我 ...

  6. Comet:基于 HTTP 长连接的“服务器推”技术解析

    原文链接:http://www.cnblogs.com/deepleo/p/Comet.html 一.背景介绍 传统web请求,是显式的向服务器发送http Request,拿到Response后显示 ...

  7. Comet:基于 HTTP 长连接的“服务器推”技术

    “服务器推”技术的应用 请访问 Ajax 技术资源中心,这是有关 Ajax 编程模型信息的一站式中心,包括很多文档.教程.论坛.blog.wiki 和新闻.任何 Ajax 的新信息都能在这里找到. c ...

  8. 转载:Comet:基于 HTTP 长连接的“服务器推”技术

    转自:http://www.ibm.com/developerworks/cn/web/wa-lo-comet/ 很多应用譬如监控.即时通信.即时报价系统都需要将后台发生的变化实时传送到客户端而无须客 ...

  9. Pure-ftpd无法连接到服务器 425错误

    今天是五一假期的前一天,闲来没事,打开自己的博客,发现很久没有备份数据了,由于工作方面的原因,自己慢慢的退出了技术界,但本人还是依然向往技术界啊!各位技术宅们,加油! 问题发现 当我打开FTP客户端软 ...

随机推荐

  1. 初探html-17 表单

    HTML 表单和输入 HTML 表单用于收集不同类型的用户输入. 在线实例 <form action=""> First name: <input type=&q ...

  2. 现身说法:面对DDoS攻击时该如何防御?

    上周,我们的网站遭到了一次DDoS攻击.虽然我对DDoS的防御还是比较了解,但是真正遇到时依然打了我个措手不及.DDoS防御是一件比较繁琐的事,面对各种不同类型的攻击,防御方式也不尽相同.对于攻击来的 ...

  3. 2019-11-29-C#-序列类为-xml-可以使用的特性大全

    title author date CreateTime categories C# 序列类为 xml 可以使用的特性大全 lindexi 2019-11-29 8:59:2 +0800 2018-6 ...

  4. 5月Linux市场Steam 份额在增长

    随着新的一个月的开始,Valve公布了上个月的软件/硬件调查数据.在2019年5月,Steam Linux的使用率按百分比略微上升. 上个月,运行Linux的Steam用户比例(根据有争议的Steam ...

  5. python-装饰器2

    python-装饰器2 1.函数既“变量 def bar(): print("in the bar") def foo(): print("in the foo" ...

  6. 第一节,搭建openwrt开发环境

    一,安装VMware虚拟机或者VirtualBox虚拟机 安装过程就不在此赘述了.附上百度搜索来的链接,供大家参考. https://baijiahao.baidu.com/s?id=16233731 ...

  7. yum 报错2

    Cannot retrieve metalink for repository: epel/x86_64. Please verify its path and try again 打开/etc/yu ...

  8. 007-Zabbix Server 自带模板监控MySQL数据库

    监控数据库分为三种: 1.Zabbix Server 自带模板监控无密码MySQL数据库 2.Zabbix Server 自带模板监控有密码MySQL数据库 3.Zabbix Server 自带模板监 ...

  9. GetShortPathName函数

    Declare Function GetShortPathName Lib "kernel32" Alias "GetShortPathName" (ByVal ...

  10. git初始化命令行指引

    Git 全局设置 git config --global user.name "陈耿聪" git config --global user.email "swain@di ...