Sagar Jethva
Sagar Jethva

Reputation: 1014

Emit or Ack timeout handling in Android socket.IO ?

When working with socket.io emitted message with callback, if the socket disconnect before answering (or doesn't answer at all) the callback function hangs up forever.In other situations where network connectivity is low and sockets are emitted but there are no callbacks if the emit was successful.

In these situations i want to implement timeout in emit callback.But there is not timeout for ACK message.

Here my socket emitting code with ACK

    JSONObject obj = new JSONObject();
    try {

        obj.put("device_id", deviceVO.getDeviceId());
        obj.put("device_status", deviceVO.getOldStatus());

    } catch (JSONException e) {
        e.printStackTrace();
    }

   mSocket.emit("socketChangeDevice", obj, new Ack() {
            @Override
            public void call(Object... args) {
                if(args!=null){
                    Ack ack = (Ack) args[args.length - 1];
                    ack.call();
                    Log.d("ACK_SOCKET","isAck : "+ ack);
                }
            }
        });

is there any better way to return a failed callback on client disconnecting ? i need to implement timeout manually ?

Upvotes: 3

Views: 2926

Answers (2)

trueangle
trueangle

Reputation: 230

Kotlin implementation

class AckWithTimeout(
    private var onSuccess: (args: Array<out Any>) -> Unit,
    private var onTimeout: () -> Unit,
    private val timeoutInMillis: Long
) : Ack {
    private var called = false

    private val timer: Timer = Timer().apply {
        schedule(object : TimerTask() {
            override fun run() {
                if (called) return
                called = true

                onTimeout()
            }
        }, timeoutInMillis)
    }

    override fun call(vararg args: Any) {
        if (called) return
        called = true
        timer.cancel()

        onSuccess(args)
    }
}

Upvotes: 0

Sagar Jethva
Sagar Jethva

Reputation: 1014

Timeout ACK with socket emit

My AckWithTimeOut custom Timeout class with implements Ack interface

public class AckWithTimeOut implements Ack {

private Timer timer;
private long timeOut = 0;
private boolean called = false;

public AckWithTimeOut() {
}

public AckWithTimeOut(long timeout_after) {
    if (timeout_after <= 0)
        return;
    this.timeOut = timeout_after;
    startTimer();
}

public void startTimer() {
    timer = new Timer();
    timer.schedule(new TimerTask() {
        @Override
        public void run() {
            callback("No Ack");
        }
    }, timeOut);
}

public void resetTimer() {
    if (timer != null) {
        timer.cancel();
        startTimer();
    }
}

public void cancelTimer() {
    if (timer != null)
        timer.cancel();
}

void callback(Object... args) {
    if (called) return;
    called = true;
    cancelTimer();
    call(args);
}

@Override
public void call(Object... args) {

}
}

add AckWithTimeOut in socket emit listener

 mSocket.emit("socketChangeDeviceAck", obj, new AckWithTimeOut(5000) {
            @Override
            public void call(Object... args) {
                if(args!=null){
                    if(args[0].toString().equalsIgnoreCase("No Ack")){
                        Log.d("ACK_SOCKET","AckWithTimeOut : "+ args[0].toString());
                    }else if(args[0].toString().equalsIgnoreCase("true")){
                       cancelTimer(); //cancel timer if emit ACK return true
                       Log.d("ACK_SOCKET","AckWithTimeOut : "+ args[0].toString());
                    }
                }
            }
        });

Upvotes: 1

Related Questions