mqtt emqx

下文以{mqttPath}代表安装目录

开启授权

  1. {mqttPath}/etc/emqx.conf关闭匿名访问
    allow_anonymous = false

  2. {mqttPath}/etc/emqx_auth_mnesia.conf 配置账号密码

  3. emqx插件中打开emqx_auth_mnesia

  4. 重启emqx

emqx.cmd start

重置dashboard密码

emqx_ctl  admins 用户名 新密码

命令行创建规则 此方法已失效

参数中前两个为必选参数:
SQL 语句: SELECT * FROM "t/a"
动作列表: [{"name":"inspect", "params": {"a": 1}}]。动作列表是用 JSON Array 格式表示的。name 字段是动作的名字,params 字段是动作的参数。注意 inspect 动作是不需要绑定资源的。
最后一个可选参数,是规则的描述: 'Rule for debug'。

emqx_ctl rules create \
  "SELECT * FROM \"t/a\" \
  '[{"name":"inspect", "params": {"a": 1}}]' \
  -d 'Rule for debug'

Rule rule:803de6db created

消息顺序

  1. 相同的主题和 QoS 下,消息是按顺序投递和应答的
  2. 如果用户期望所有主题下的 QoS 1 与 QoS 2 消息都严格有序,那么需要设置飞行窗口的最大长度为 1,但代价是会降低该客户端的吞吐
    相关配置项
    | 配置项 | 类型 | 可取值 | 默认值 | 说明 |
    | ----------------- | -------- | ----------- | ---- | --------------------------- |
    | mqueue_store_qos0 | bool | true, false | true | 是否将 QoS 0 消息存入消息队列中 |
    | max_mqueue_len | integer | >= 0 | 1000 | 消息队列长度 |
    | max_inflight | integer | >= 0 | 0 | 飞行窗口大小;默认 0 即无限制 |
    | max_awaiting_rel | integer | >= 0 | 0 | 最大接收;默认 0 即无限制 |
    | await_rel_timeout | durtaion | > 0 | 300s | 最大接收 中消息等待释放的最大超时时间;超过则直接丢弃 |

clean session & sessionIntervalTime

会话(session):将从客户端向服务端发起 MQTT 连接请求开始,到连接中断直到会话过期为止的消息收发序列称之为会话
clientid:并不是指客户端id,更多的是指代会话id(也可以理解成session的功能是依托在clientid之上来实现的,所以如果clientid不同时无法实现基于会话的功能)。

clean session代表每次连接服务器时是否需要清空同一个clientid之前的会话,设置clean session为false后断线后未处理的消息就可以继续处理。
需要注意的是未处理的消息需要在短线后指定的超时间隔内才会被再次发送,此配置为 sessionIntervalTime (单位为秒,默认为0-即所有数据不重新发送)

保留消息

同一个主题只会有一条数据为保留消息。

消息持久化

消息可以配置持久化到磁盘,同时可以设置持久化磁盘的消息数量,默认为不限制。
另外持久化为企业版功能

异常重传

异常重传会在客户端断开重连后发生异常,根据官方文档,此问题在企业版4.4.12中进行修复,测试后开源版5.1也还是有这个问题,
如果有知道开源版如何修复此问题的望告知,暂时处理方法是重启后往订阅的主题发送一条QoS0的数据来通知发送发重新传数据,这个周期重发的机制就会重新触发了。


文档位置

如果使用mqttnet来处理业务异常,可以通过ProcessingFailed来控制是否发送ACK指令,设置为true则不会确认此消息完成,后续便会重传数据

mqttClient.ApplicationMessageReceivedAsync += e =>
{
  try
  {
    action?.Invoke(e.ApplicationMessage.ConvertPayloadToString());
  }
  catch (Exception)
  {
    e.ProcessingFailed = true;
    //Console.WriteLine(DateTime.Now.ToString("HH:mm:ss"));
  }

  return Task.CompletedTask;
};
posted @ 2022-06-23 11:25  Hey,Coder!  阅读(285)  评论(0编辑  收藏  举报