Search code examples
androidsocket.iosocket.io-java-client

cannot keep socket connection when screen off in android


I have trouble to keep socket connection in android.

I use Socket.IO-client java library in my application.

The socket connection is keeped when screen on.

but, if screen off, the socket is disconnected caused by ping timeout.

how can i solve this problem?

I open connection like this.

private static final String EVENT_CONNECT = Socket.EVENT_CONNECT;
private static final String EVENT_MESSAGE = Socket.EVENT_MESSAGE;
private static final String EVENT_DISCONNECT = Socket.EVENT_DISCONNECT;
private static final String EVENT_PING = Socket.EVENT_PING;
private static final String EVENT_CONNECT_TIMEOUT = Socket.EVENT_CONNECT_TIMEOUT;
private static final String EVENT_ERROR = Socket.EVENT_ERROR;

public void connect() {
    if (socket != null && socket.connected() == true) {
        return;
    }
    IO.Options options = new IO.Options();

    options.timeout = 60 * 1000;
    options.reconnection = true;

    Log.d(TAG, "try socket connect");
    socket.on(EVENT_CONNECT, this::onConnected)
            .on(EVENT_MESSAGE, this::onMessage)
            .on(EVENT_DISCONNECT, this::onDisconnected)
            .on(EVENT_PING, this::onPing)
            .on(EVENT_CONNECT_TIMEOUT, this::onConnectTimeout)
            .on(EVENT_ERROR, this::onError);

    socket.connect();
}

And this is my server side code

var Socket = require('socket.io');
var io = Socket(server, { 'pingInterval': 25 * 1000 });
var port = process.env.PORT || 3000;

io.on('connection', function(socket){
    console.log('a user connected');

    ...

    socket.on('disconnect', function(data){
        (typeof socket.member != 'undefined') && disconnect(socket);
        console.log(data);
    });
});

ping interval is 25 second, and timeout is 60 second.

when android screen is off, client do not work for EVENT_PING. the other event work correctly.

and server is disconnected with log(ping timeout).


Solution

  • I solve this problem like below:

    private static final String EVENT_PING = "ping1";
    private static final String EVENT_PONG = "pong1";
    
    public void connect() {
        if (socket != null && socket.connected() == true) {
            return;
        }
        IO.Options options = new IO.Options();
    
        options.timeout = 60 * 1000;
        options.reconnection = true;
    
        Log.d(TAG, "try socket connect");
        socket.on(EVENT_CONNECT, this::onConnected)
                .on(EVENT_MESSAGE, this::onMessage)
                .on(EVENT_DISCONNECT, this::onDisconnected)
                .on(EVENT_PING, this::onPing)
                .on(EVENT_CONNECT_TIMEOUT, this::onConnectTimeout)
                .on(EVENT_ERROR, this::onError);
    
        socket.connect();
    }
    
    private void onPing(Object... args) {
        Log.d(TAG, "socket ping");
        socket.emit(EVENT_PONG);
    }
    

    This is server code.

    var pingInterval = 25 * 1000;
    var Socket = require('socket.io');
    var io = Socket(server, { 'pingInterval': pingInterval });
    var port = process.env.PORT || 3000;
    
    io.on('connection', function(socket){
        console.log('a user connected');
    
        function sendPing() {
            socket.emit('ping1');
        }
    
        setTimeout(sendPing, pingInterval);
    
        socket.on('disconnect', function(data){
            (typeof socket.member != 'undefined') && disconnect(socket);
            console.log(data);
        });
    
        socket.on('pong1', function(data) {
            setTimeout(sendPing, pingInterval);
            console.log('pong');
        });
    });