Android 套接字中的发出或确认超时处理.IO ?



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

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

这是我的套接字发出代码与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自定义超时类,带有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) {
}
}

在套接字发出侦听器中添加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());
}
}
}
});

Kotlin 实现

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

最新更新