tlmqtt 是一款基于Java
开发的轻量级高并发MQTT Broker
,采用Netty
和Project Reactor
实现异步通信,完整支持MQTT 3.1.1 协议,包括QoS 消息分级、主题通配符、消息持久化等核心功能。项目采用模块化设计,提供认证(文件/数据库/HTTP) 、数据桥接(Kafka/MySQL )和存储(内存/Redis)等可扩展组件,支持MQTT 和WebSocket 双协议接入。具备生产级特性如SSL加密、会话恢复及高并发处理能力,适用于物联网和实时通信场景。
认证
mqtt
协议规定了CONNECT 包含有Username
和Password
字段。实现可以选择如何使用这些字段的内容。他们也可能提供自己的认证机制,使用额外的认证系统。 而tlmqtt 实现了基本文件 ,mysql 和http接口的3种认证方式,并且提供了扩展让用户自行去实现认证方式并添加到认证链中,其中只要有任何一个认证通过了,那么此次客户端连接就是通过的
tlmqtt 认证原理
tlmqtt 存在一个抽象类AbstractTlAuthentication
它定义了认证相关的抽象方法,有具体的认证器去实现
php
/**
* 认证接口
* @author hszhou
* @datetime: 2025-05-10 10:51:55
* @param username 用户名
* @param password 密码
* @return boolean 是否成功
**/
abstract public boolean authenticate(String username, String password);
/**
* 是否启用了该认证器
* @author hszhou
* @datetime: 2025-05-12 10:11:26
* @return boolean 是否启用
**/
abstract public boolean enabled();
/**
* 添加新的认证主体
* @author hszhou
* @datetime: 2025-05-15 17:53:17
* @param object 添加的认证实体
**/
abstract public void add(Object object);
NoneAuthenticationService
tlmqtt 是可以通过一个配置来进行关闭客户端的认证的。
yml
auth:
enabled: true #是否开启认证 false就是关闭认证
其实现原理就是通过NoneAuthenticationService
这个认证器。也是认证链中的第一个认证器。
typescript
@Override
public boolean authenticate(String username, String password) {
return true;
}
其主要实现了authenticate
方法返回的是true
。NoneAuthenticationService
并不关心客户端的用户名和密码,也就是无论用户名和密码是什么,他都不会在意,只会返回true
。表示认证通过,而enabled
方法返回的就是是否开启,一旦开启了,那么这个authenticate
就会执行。由于处于认证链的首位。只要通过了就不会执行其他的认证了。
FixTlAuthentication
FixTlAuthentication
是基于固定用户的认证方式。其固定的用户的配置方式有2种, 第一种是基于文件的,这种方式是提前将用户写入到配置文件中
yml
auth:
enabled: true #是否开启认证 false就是关闭认证
user: #开启认证后fix的认证信息
- username: watson
password: 12345
- username: zhouhs
password: 12345
第二种方式是基于编程的tlmqtt启动引导类支持动态添加用户
java
tlBootstrap.setFixUser(Collections.singletonList(new TlUser("admin","12345")))
FixTlAuthentication
的内部维护了一个用户列表,authenticate
方法就是将客户端的用户名与密码将内部的用户列表继续依次匹配。只要有任何一个匹配成功就返回。
java
public boolean authenticate(String username, String password) {
if(users.isEmpty()){
return false;
}
for (TlUser user : users) {
if (user.getUsername().equals(username) && user.getPassword().equals(password)) {
log.debug("username = 【{}】,password = 【{}】 pass",username,password);
return true;
}
}
return false;
}
而编程式的添加用户就是往内部的用户列表中添加用户
java
@Override
public void add(Object object) {
if( object instanceof TlUser){
log.debug("join fix authentication user 【{}】",object);
this.users.add((TlUser) object);
}
}
HttpTlAuthentication
HttpTlAuthentication
认证器是基于http
请求的认证器。也是tlmqtt 的内置认证器之一。通过将用户名与密码当做参数请求第三方的API进行认证。只要API
返回的状态码为200 ,注意的是这里的状态码200 是HTTP
的状态码,而不是第三方系统自己定义的200 . tmqtt 将http
请求封装成一个对象HttpEntityInfo
。里面有API
的地址,参数等等信息
java
public class HttpEntityInfo {
/**请求的地址*/
private String url;
/**方法类型 post或者get*/
private String method;
/**请求头*/
private HashMap<String, String> headers;
/**用户的参数 例如 参数是uname 与pwd 那么这个params的参数就是("username","uname") ("password","pwd")*/
private HashMap<String,String> params;
}
HttpTlAuthentication
将认证接口大致分为3类,
POST
请求的form
表单提交POST
请求的json
数据提交GET
请求
最终只要请求返回的是200就认证认证成功
HttpTlAuthentication
认证过滤器不单单可以设置一个API
。可以通过多个API
接口组成的集合进行认证。其内部维护了一个HttpEntityInfo
的集合。只要任何一个API通过,及认证通过
java
private final List<HttpEntityInfo> httpEntityInfos;
HttpTlAuthentication
提供了动态添加http
接口的方式
java
@Override
public void add(Object object) {
if (object instanceof HttpEntityInfo) {
this.httpEntityInfos.add((HttpEntityInfo) object);
}
}
使用方式
java
HttpEntityInfo entityInfo = AuthenticationHttpProvider.formLogin();
HttpEntityInfo login = AuthenticationHttpProvider.getLogin();
tlBootstrap.addAuthEntity(entityInfo)
.addAuthEntity(login)
SqlTlAuthentication
SqlTlAuthentication
认证器是基于mysql数据库的认证,tlmqtt 将SqlTlAuthentication
的数据封装成了一个SQL对象SqlEntityInfo
。
java
/**地址*/
private String host;
/**端口号*/
private String port;
/**用户名*/
private String username;
/**密码*/
private String password;
/**数据库名*/
private String database;
/**表名*/
private String table;
/**用户名字段*/
private String usernameColumn;
/**密码字段*/
private String passwordColumn;
private String driverClassName;
如果需要使用到SqlTlAuthentication
认证过滤器,就需要添加相应的SqlEntityInfo
。SqlEntityInfo
设置数据库的地址,表名和用户名和密码的字段。然后其内部维护了一个SqlEntityInfo
集合,与http
认证器一致,只要有任何一个认证通过即可,当用户设置成功后,tlmqtt 会执行内部的sql
语句并替换相应的参数
sql
private static final String SQL = "SELECT COUNT(*) FROM %s WHERE %s = ? AND %s = ?";
SqlTlAuthentication
提供动态方法新增SqlEntityInfo的方式。使用方法
java
SqlEntityInfo sqlEntityInfo = AuthenticationMysqlProvider.providerDemo();
tlBootstrap .addAuthEntity(sqlEntityInfo)
可扩展的认证链
当上述认证器不满足系统的认证方式,tlmqtt 提供了可扩展的认证器。是需要用户继承AbstractTlAuthentication
类即可。然后实现authenticate
方法。然后通过辅助引导类TlBootstrap
的addAuthentication
方法即可。
实现AbstractTlAuthentication类
java
@Slf4j
public class NoneA extends AbstractTlAuthentication {
@Override
public boolean authenticate(String username, String password) {
return true;
}
@Override
public boolean enabled() {
return true;
}
@Override
public void add(Object object) {
}
}
添加认证器
java
tlBootstrap.addAuthentication(new NoneA())
这样就可以将自定义的认证器添加到tlmqtt
的整个认证体系中。
结语
欢迎通过以下方式参与项目共建:
- 提交 Issue:反馈 Bug 或提出功能建议
- 提交 PR:优化代码或新增功能(建议先创建 Issue 沟通方案)
- Star/Fork:支持项目持续发展
联系方式:
tlmqtt致力于为物联网开发者提供轻量、高效的 MQTT 消息服务,期待您的加入! 🚀
本文由博客一文多发平台 OpenWrite 发布!