mqtt经过12小时后断线并且重连后依然会断线

mqtt连接后,经过12小时,必定通过connectionLost的回调得到下记错误发生断线。
已断开连接 (32109) - java.io.EOFException

虽然已经设定了setAutomaticReconnect(TRUE),断线后会进行自动重连。但是重连后依然会断线。

目前原因不明,没有解决方案,希望有人能解答我的困惑。
已知情况:
1.排除无重复clientid的客户端,网络状况也是OK的,app关闭再启动后也是OK的。
2.基本上,连接后的12小时左右后或者15小时左右后发生再现,且是必现。
3.mqtt服务端无法看到代码以及log,所以只能从客户端来推测以及修改。

log4j(112): 2021-08-31 07:38:54,004 - [] - ERROR : MainService connectionLost:已断开连接 (32109) - java.io.EOFException
log4j(116): 2021-08-31 07:38:55,399 - [] - ERROR : MainService @@@@@reconnect Successs: serverURI:ssl://192.168.130.80:8883
log4j(292): 2021-08-31 07:39:35,046 - [] - ERROR : MainService connectionLost:已断开连接 (32109) - java.io.EOFException
log4j(296): 2021-08-31 07:39:36,451 - [] - ERROR : MainService @@@@@reconnect Successs: serverURI:ssl://192.168.130.80:8883
log4j(472): 2021-08-31 07:39:48,101 - [] - ERROR : MainService connectionLost thread fconnect:false
log4j(473): 2021-08-31 07:40:16,082 - [] - ERROR : MainService connectionLost:已断开连接 (32109) - java.io.EOFException
log4j(477): 2021-08-31 07:40:17,475 - [] - ERROR : MainService @@@@@reconnect Successs: serverURI:ssl://192.168.130.80:8883
log4j(653): 2021-08-31 07:40:57,015 - [] - ERROR : MainService connectionLost:已断开连接 (32109) - java.io.EOFException
log4j(657): 2021-08-31 07:40:58,439 - [] - ERROR : MainService @@@@@reconnect Successs: serverURI:ssl://192.168.130.80:8883
log4j(833): 2021-08-31 07:41:38,050 - [] - ERROR : MainService connectionLost:已断开连接 (32109) - java.io.EOFException
log4j(837): 2021-08-31 07:41:39,440 - [] - ERROR : MainService @@@@@reconnect Successs: serverURI:ssl://192.168.130.80:8883

你的mqtt服务器 是用哪个broker搭建的

试试看 options.setKeepAliveInterval(20);
options.setConnectionTimeout(10);
options.setKeepAliveInterval(20);
// waitForCompletion等待时间
client.setTimeToWait(1000);
client.connect(options);
————————————————
版权声明:本文为CSDN博主「格一物」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接: 记-tomcat启动阻塞问题_ory001的博客-CSDN博客 一、现象描述重新发布项目war包时,启动tomcat无限期阻塞(突发现象),tomcat服务无法访问;经测试webapp文件夹下只保留ROOT项目即tomcat欢迎页时,tomcat服务可以正常访问!二、排查步骤1.使用jvisualvm.exe(JDK自带工具)查询线程执行情况重点观察tomcat主线程、运行中的线程2.jvisualvm.exe 线程dump或jstack -l pid命令截取关键内容:"MQTT Rec: 2021-03-28 08:37:28 558" dae https://blog.csdn.net/ory001/article/details/115287691

经过多天测试,发现是心跳包突然不发导致的断线,心跳包不发原因不明。
6:00:22 本应该有类似 AlarmPingSender: Sending Ping的log。

09-01 05:59:42.456  1650  1650 D AlarmPingSender: Sending Ping at:1630447182456
09-01 05:59:42.461  1650  1650 D AlarmPingSender: Schedule next alarm at 1630447202461
09-01 05:59:42.462  1650  1650 D AlarmPingSender: Alarm scheule using setExactAndAllowWhileIdle, next: 20000
09-01 05:59:42.466  1650  1750 D AlarmPingSender: Success. Release lock(MqttService.client.d4c21d45-7ffa-4c1d-8da5-245c32547e4b):1630447182466
09-01 05:59:51.267   498   508 I system_server: Background concurrent copying GC freed 181076(5MB) AllocSpace objects, 0(0B) LOS objects, 42% free, 7MB/12MB, paused 392us total 165.345ms
09-01 06:00:00.734   498   508 I system_server: Background concurrent copying GC freed 176899(5MB) AllocSpace objects, 0(0B) LOS objects, 42% free, 7MB/12MB, paused 425us total 163.132ms
09-01 06:00:02.465  1650  1650 D AlarmPingSender: Sending Ping at:1630447202465
09-01 06:00:02.470  1650  1650 D AlarmPingSender: Schedule next alarm at 1630447222470
09-01 06:00:02.470  1650  1650 D AlarmPingSender: Alarm scheule using setExactAndAllowWhileIdle, next: 20000
09-01 06:00:02.474  1650  1750 D AlarmPingSender: Success. Release lock(MqttService.client.d4c21d45-7ffa-4c1d-8da5-245c32547e4b):1630447202474
09-01 06:00:06.028   331   386 E storaged: getDiskStats failed with result NOT_SUPPORTED and size 0
09-01 06:00:10.275   498   508 I system_server: Background concurrent copying GC freed 182162(5MB) AllocSpace objects, 0(0B) LOS objects, 42% free, 7MB/12MB, paused 474us total 165.996ms
09-01 06:00:19.871   498   508 I system_server: Background concurrent copying GC freed 179790(5MB) AllocSpace objects, 0(0B) LOS objects, 42% free, 7MB/12MB, paused 516us total 159.611ms
09-01 06:00:24.286   303   339 V vdroid.netdev.ethernet: fvlNetDevEthActiveNetInfoGet
09-01 06:00:24.287   498   806 V vdroid.ipc.FvlNetworkProxyClient: FvlNetworkProxyClient::getActiveNetInfo
09-01 06:00:24.287   498   806 V EthernetNativeInterface: getActiveNetInfo start!
09-01 06:00:24.287   498   806 D EthernetNativeInterfaceJava: getActiveNetInfo: 
09-01 06:00:24.296   498   806 V vnetNetworkProfileWrapper: createFvlNetInfo
09-01 06:00:24.297   498   806 V vnetNetworkProfileWrapper: dumpFvlNetInfo: fvlNetInfo_t { Type: 0 SubType: 0 State: 0 Reason: 0 ifName:  ipAddress: 192.168.130.150 subnetMask: 0.0.0.0 gateway: 0.0.0.0 PrimaryDns: 0.0.0.0 SecondaryDns: 0.0.0.0}
09-01 06:00:24.297   498   806 V EthernetNativeInterface: getActiveNetInfo: fvlNetInfo_t { Type: 0 SubType: 0 State: 0 Reason: 0 ifName:  Mac Address: 0C:38:3E:37:5A:F9 ipAddress: 192.168.130.150 subnetMask: 0.0.0.0 gateway: 0.0.0.0 PrimaryDns: 0.0.0.0 SecondaryDns: 0.0.0.0}
09-01 06:00:24.297   303   339 V vdroid.nmdev: nmGetMacAddress: fvlNetInfo_t { Type: 0 SubType: 0 State: 0 Reason: 0 ifName:  Mac Address: 0C:38:3E:37:5A:F9 ipAddress: 192.168.130.150 subnetMask: 0.0.0.0 gateway: 0.0.0.0 PrimaryDns: 0.0.0.0 SecondaryDns: 0.0.0.0}
09-01 06:00:24.298   303   339 V vdroid.netdev.ethernet: fvlNetDevEthActiveNetInfoGet
09-01 06:00:24.298   498   550 V vdroid.ipc.FvlNetworkProxyClient: FvlNetworkProxyClient::getActiveNetInfo
09-01 06:00:24.298   498   550 V EthernetNativeInterface: getActiveNetInfo start!

从源码来看,上面的AlarmPingSender: Sending Ping的log所在的onReceive在6:00:22这一时间点应该是没有被调用。

class AlarmReceiver extends BroadcastReceiver {
        private WakeLock wakelock;
        private final String wakeLockTag = MqttServiceConstants.PING_WAKELOCK
                + that.comms.getClient().getClientId();

        @Override
        @SuppressLint("Wakelock")
        public void onReceive(Context context, Intent intent) {
            // According to the docs, "Alarm Manager holds a CPU wake lock as
            // long as the alarm receiver's onReceive() method is executing.
            // This guarantees that the phone will not sleep until you have
            // finished handling the broadcast.", but this class still get
            // a wake lock to wait for ping finished.

            Log.d(TAG, "Sending Ping at:" + System.currentTimeMillis());

            PowerManager pm = (PowerManager) service
                    .getSystemService(Service.POWER_SERVICE);
            wakelock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, wakeLockTag);
            wakelock.acquire();

            // Assign new callback to token to execute code after PingResq
            // arrives. Get another wakelock even receiver already has one,
            // release it until ping response returns.
            IMqttToken token = comms.checkForActivity(new IMqttActionListener() {

                @Override
                public void onSuccess(IMqttToken asyncActionToken) {
                    Log.d(TAG, "Success. Release lock(" + wakeLockTag + "):"
                            + System.currentTimeMillis());
                    //Release wakelock when it is done.
                    wakelock.release();
                }

                @Override
                public void onFailure(IMqttToken asyncActionToken,
                                      Throwable exception) {
                    Log.d(TAG, "Failure. Release lock(" + wakeLockTag + "):"
                            + System.currentTimeMillis());
                    //Release wakelock when it is done.
                    wakelock.release();
                }
            });


            if (token == null && wakelock.isHeld()) {
                wakelock.release();
            }
        }
    }

MQTT灭屏下断开连接分析_lifengjiang123的博客-CSDN博客 速度达到所多撒多 https://blog.csdn.net/lifengjiang123/article/details/118386956?spm=1001.2014.3001.5501
根据这篇文章。将ping设定的定时器函数setExactAndAllowWhileIdle修改为setAlarmClock居然就好了。
明明也没有灭屏,很奇怪,这几天继续试。

经过周末的测试,本问题不再发生,认为已解决。