Reputation: 1014
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
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
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