keepalive doesn't work on android 4.2

Asked by howard

Hi, I'm using libmosquitto on android platform. And I have run it perfectly on android 2.3.
But on android 4.2, the keepalive (which I have set to 180s.) doesn't work. It is When I disconnect the network, I immediately receive the DISCONNECT callback from mosquitto. And I can't connect to server any more.
It made me confused. Please help. Thanks!

Question information

Language:
English Edit question
Status:
Answered
For:
mosquitto Edit question
Assignee:
No assignee Edit question
Last query:
Last reply:
Revision history for this message
Roger Light (roger.light) said :
#1

I'm not sure I've understood your problem properly. It sounds like you are saying that if you disconnect the network, you can't connect to the server. Is that what you mean? The point of keepalive is to help detect when the network disconnects.

If there is a difference in behaviour between android 2.3 and 4.2, it must be that they have changed the way the network stack works. It sounds like the network informs the application much quicker that the network has been disconnected, hence why the disconnect callback has been called. If this wasn't happening the same way in 2.3, then it would take over 180s until the disconnect was detected.

Revision history for this message
howard (hzd2712) said :
#2

Thanks, Roger! It's exactly what I say.
So you mean it dues to android network behaviour has been changed. Right?

I debug the libmosquitto, and found something different between android 2.3 and 4.2.

On android 4.2, when I do the operation as I described above (disconnect the network),
In mosquitto.c, mosquitto_loop(), the code block will be executed, as below:

                 if(FD_ISSET(mosq->sock, &readfds)){
   rc = mosquitto_loop_read(mosq, max_packets);

   if(rc){
    _mosquitto_socket_close(mosq);
    pthread_mutex_lock(&mosq->state_mutex);
    if(mosq->state == mosq_cs_disconnecting){
     rc = MOSQ_ERR_SUCCESS;
    }
    pthread_mutex_unlock(&mosq->state_mutex);
    pthread_mutex_lock(&mosq->callback_mutex);
    if(mosq->on_disconnect){
     mosq->in_callback = true;
     mosq->on_disconnect(mosq, mosq->obj, rc);
     mosq->in_callback = false;
    }
    pthread_mutex_unlock(&mosq->callback_mutex);
    return rc;
   }
  }
But on android 2.3, the logic is _mosquitto_check_keepalive(), which will send PINREQ, until the disconnect comes.
Maybe FD_ISSET(mosq->sock, &readfds) causes the problem on android 4.2, which is a part of socket in linux.

I don't know what's the different between android 2.3 and 4.2 about this part.

Revision history for this message
Roger Light (roger.light) said :
#3

Right, so you confirm what I've said - this is a change (in fact an improvement) in the way android handles socket connections when the network disappears. If your connection drops, you want to know about it as soon as possible, so android 4.2 is doing the right thing. It's not a problem either way, it's just different behaviour. In both cases you aren't connected to the broker and won't be able to until the connection is restored.

Revision history for this message
howard (hzd2712) said :
#4

Thank you, Roger! You saved my life!
So as you said, the keepalive has no meaning on android 4.2.
When the network is broken, I must reconnect to the server manually. However, In some situations network is mutable,
for example in the subway, the network will auto restore quickly after it disappeared, at this time, the keepalive can make
effect (because I don't want to make a reconnect.)

Thans again!

Can you help with this problem?

Provide an answer of your own, or ask howard for more information if necessary.

To post a message you must log in.