Android socket.IO中的Emit或Ack超时处理?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android socket.IO中的Emit或Ack超时处理?相关的知识,希望对你有一定的参考价值。

当使用带回调的socket.io发出消息时,如果套接字在应答之前断开连接(或者根本没有应答),则回调函数将永久挂起。在网络连接较低且发出套接字但在没有回调的情况下,如果发射成功。

在这些情况下,我想在emit回调中实现超时。但是ACK消息没有超时。

这里我的socket用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);
                }
            }
        });

是否有更好的方法可以在客户端断开连接时返回失败的回调?我需要手动实现超时?

答案

带套接字发出的超时ACK

我的AckWithTimeOut自定义Timeout类与实现Ack接口

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) {

}
}

在socket发出监听器中添加AckWithTimeOut

 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());
                    }
                }
            }
        });

以上是关于Android socket.IO中的Emit或Ack超时处理?的主要内容,如果未能解决你的问题,请参考以下文章

io.emit 与 socket.emit

Socket.IO初探

socket.io - socket.emit、socket.on、socket.send

io.sockets.socket(socket_id).emit() - 没有方法'socket'

unity5 中的 Socket.IO,C# - 如何发出字符串或对象?

socket.io的emit使用清单