Mosquitto之Durable Connection超时断开与删除

本文章将进入mosquitto源码,介绍几个与客户端相关的时间变量,初探这些变量的含义。由于能力有限,如有错误,欢迎批评指正。注意:以下主要针对Durable Connection而言。

  • keepalive:对应于mosquitto.conf中的max_keepalive配置选项,表示broker与client(桥模式的client除外)之间交互时,报文的最大有效时间,这个时间也可以成为保活时间,目前在mosquitto的实现中,保活时间被放大到1.5倍。客户端超时后,连接将会断开。
  • persistent_client_expiration:Durable Connection超时时间。
  • session_expiry_interval:连接会话间隔时间。存在两个特殊值:0表示立即删除会话,UINT32_MAX表示永不删除会话。在MQTT V5版本以前,本值默认为UINT32_MAX。

以上几个变量之间的关系如下:

1、keepalive大于0,如果是,则如果客户端在1.5倍的时间内未发送报文,那么broker将主动断开与该客户端的连接。keepalive等于0时表示永远存活。桥模式下的客户端不受本参数影响,即:永不超时。

if(!(context->keepalive)
	|| context->bridge
	|| now - context->last_msg_in <= (time_t)(context->keepalive)*3/2){
    ....
} else {
    /* Client has exceeded keepalive*1.5 */
    do_disconnect(db, context, MOSQ_ERR_KEEPALIVE);
}

2、连接断开之后,mosquitto将检查连接会话的间隔时间(session_expiry_interval)。如果该变量等于0,那么直接删除该clientid。如果该变量等于UINT32_MAX,则该clientid表示的会话信息将永久保存。如果大于0,且不等于UINT32_MAX,进入下个步骤。

if(context->sock == INVALID_SOCKET 
   && context->session_expiry_interval > 0
   && context->session_expiry_interval != UINT32_MAX)
{
    /* This is a persistent client, check to see if the
	 * last time it connected was longer than
	 * persistent_client_expiration seconds ago. If so,
	 * expire it and clean up.
	 */
	if(now > context->session_expiry_time) {
		...
		G_CLIENTS_EXPIRED_INC();
		context->session_expiry_interval = 0;
		mosquitto__set_state(context, mosq_cs_expiring);
		do_disconnect(db, context, MOSQ_ERR_SUCCESS);
	}
}

3、如果persistent_client_expiration大于0,mosquitto根据的persistent_client_expiration值与session_expiry_interval进行比较,选择其中最小的值作为该会话的超时时间;如果persistent_client_expiration值未配置,那么将使用session_expiry_interval的值作为超时时间,并把该会话的信息添加到过期列表中。

item->context->session_expiry_time = time(NULL);
if(db->config->persistent_client_expiration == 0
  || db->config->persistent_client_expiration < item->context->session_expiry_interval)
{
    item->context->session_expiry_time += item->context->session_expiry_interval;
} else {
    item->context->session_expiry_time += db->config->persistent_client_expiration;
}
context->expiry_list_item = item;

DL_INSERT_INORDER(expiry_list, item, session_expiry__cmp);
...

4、该客户端未在超时时间内进行重连,broker会将客户端的会话信息删除回收。由于broker中该会话信息已经被删除,因此假设客户端断开之后,broker在该topic上接收到了很多消息,那么这些消息以后也将不会再发送给该客户端。对于永久存活的客户端,Qos大于0的消息在后续客户端重连的时候,这些客户端仍然能够接收到那些消息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值