Gmqtt——Go语言实现的MQTT broker

MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议)是用于物联网(IoT)的OASIS标准消息传递协议。发布/订阅是连接远程消息传递设备的理想选择,因为它具有非常小的网络带宽。MQTT目前广泛应用于各种行业,如汽车、制造业、电信、石油和天然气等。

摘自 https://mqtt.org/

对于MQTT broker,目前主流的实现有EMQ,mosquito,HiveMQ等,但是并没有一个很完整的Go语言实现。目前的开源的Go实现对MQTT协议的支持基本上都是缺胳膊少腿,而Gmqtt完整的实现了MQTT V3.1.1和最新的V5协议,应该是Go语言中对MQTT协议支持最完整的项目。

项目地址: https://github.com/DrmagicE/gmqtt

Gmqtt的诞生是由于之前工作的项目需要,要在MQTT broker里面定制化许多业务逻辑,调研了一些broker都不尽满意,于是乎就撸起袖子自己干,造了这么一个轮子。起初只支持V3.1.1版本,但本着尽善尽美的原则(本人有强迫症),放弃了撸铁时间,肝了一段时间,把V5的特性也全部支持了。

快速开始

跟所有的Go项目一样,go get下载即可。

$ go get -u github.com/DrmagicE/gmqtt
$ cd cmd/gmqttd
$ go run . start -c default_config.yml
2020-12-13T23:11:54.037+0800    INFO    server/server.go:996    init plugin hook wrappers
2020-12-13T23:11:54.037+0800    INFO    server/server.go:802    open persistence succeeded      {"type": "memory"}
2020-12-13T23:11:54.037+0800    INFO    server/server.go:825    init session store succeeded    {"type": "memory", "session_total": 0}
2020-12-13T23:11:54.037+0800    INFO    server/server.go:842    init queue store succeeded      {"type": "memory", "session_total": 0}
2020-12-13T23:11:54.037+0800    INFO    server/server.go:843    init subscription store succeeded       {"type": "memory", "client_total": 0}
2020-12-13T23:11:54.037+0800    INFO    server/server.go:1218   loading plugin  {"name": "prometheus"}
2020-12-13T23:11:54.037+0800    INFO    server/server.go:1218   loading plugin  {"name": "admin"}
2020-12-13T23:11:54.038+0800    INFO    server/server.go:1259   starting gmqtt server   {"tcp server listen on": ["[::]:1883"], "websocket server listen on": [":8883"]}

使用上述的命令将使用默认配置default_config.yml启动gmqtt,监听1883端口提供TCP服务和8883端口提供websocket服务。Gmqtt默认配置没有启用鉴权,客户端不需配置鉴权可以直接连接。

特点

Gmqtt具备极强的扩展性,你几乎可以通过定制化插件来定制任何逻辑。例如通过HTTP/gRPC接口来查询客户端信息,强制断开连接,订阅主题,发布消息等等。这极强的扩展性得益于gmqtt提供的丰富的钩子函数,以及其内置的扩展接口。

钩子函数

目前,gmqtt提供了17个钩子函数。

hook 说明 用途示例
OnAccept TCP连接建立时调用 TCP连接限速,黑白名单等.
OnStop Broker退出时调用
OnSubscribe 收到订阅请求时调用 校验订阅是否合法
OnSubscribed 订阅成功后调用 统计订阅报文数量
OnUnsubscribe 取消订阅时调用 校验是否允许取消订阅
OnUnsubscribed 取消订阅成功后调用 统计订阅报文数
OnMsgArrived 收到消息发布报文时调用 校验发布权限,改写发布消息
OnBasicAuth 收到连接请求报文时调用 客户端连接鉴权
OnEnhancedAuth 收到带有AuthMetho的连接请求报文时调用(V5特性) 客户端连接鉴权
OnReAuth 收到Auth报文时调用(V5特性) 客户端连接鉴权
OnConnected 客户端连接成功后调用 统计在线客户端数量
OnSessionCreated 客户端创建新session后调用 统计session数量
OnSessionResumed 客户端从旧session恢复后调用 统计session数量
OnSessionTerminated session删除后调用 统计session数量
OnDeliver 消息从broker投递到客户端后调用
OnClosed 客户端断开连接后调用 统计在线客户端数量
OnMsgDropped 消息被丢弃时调用

https://github.com/DrmagicE/gmqtt/blob/master/server/hook.go#L11

举其中常用的OnBasicAuth,OnSubscribe,OnMsgArrived为例,说明如何通过这些函数来定制化鉴权逻辑。
我们在内存中保存以下6个客户端的用户名密码。

var validUser = map[string]string{
	"root":           "pwd", // root用户拥有所有权限
	"qos0":           "pwd", // qos0用户最高只允许订阅qos0主题
	"qos1":           "pwd", // qos1用户最高只允许订阅qos1主题
	"publishonly":    "pwd", // publishonly用户只允许发布,不允许订阅
	"subscribeonly":  "pwd", // subscribeonly用户只允许订阅,不允许发布
	"disable_shared": "pwd", // disable_shared用户禁止订阅表示共享订阅的主题(V5特性)
}

除去以上的针对用户的权限设置外,假设我们由于性能因素的考虑,只允许发布QoS1的消息,忽略所有QoS2消息。

登录鉴权

//authentication
var onBasicAuth server.OnBasicAuth = func(ctx context.Context, client server.Client, req *server.ConnectRequest
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值