断开连接/出错时清除socket.io缓冲区

3

1) 在断开连接模式下,我正在向服务器发送一些数据,当出现套接字错误时,我会显示消息“请检查您的互联网连接并重试”。

2) 当套接字重新连接时,它会将步骤1的数据发送到服务器(根据功能应该被丢弃)。

我不知道关闭/断开连接是否清除缓冲区,我也希望在连接可用时自动重新连接。 我正在创建Android应用程序并使用socket.io。


1
相关信息请查看此处:https://dev59.com/6FwY5IYBdhLWcg3w2K7c#32261523。 - jfriend00
谢谢您的帮助。我是Java的新手,所以这个问题可能看起来很傻。我正在使用socket.io.client库(chttps://github.com/socketio/socket.io-client-java)在我的Socket类中,我有一个sendBuffer(它是私有类变量,因此无法访问)(src/main/java/io/socket/client/Socket.java) private final Queue<Packet<JSONArray>> sendBuffer = new LinkedList<Packet<JSONArray>>();唯一具有sendBuffer的公共方法public Emitter emit(final String event, final Object... args) { //很多代码(这些代码正在修改某些私有类变量,因此无法覆盖。 - me_astr
如果(Socket.this.connected) { Socket.this.packet(packet); } else { Socket.this.sendBuffer.add(packet); }你能否提供一些清除sendBuffer的建议? 我也尝试克隆这个存储库,然后将其添加为模块,但是它还有很多其他依赖项,因此会产生许多编译错误。 - me_astr
1
如果你正在使用Java编程,我就无能为力了。你的问题没有打上Java标签(我刚刚添加了这个标签到你的问题中),所以我错误地认为你是在用Javascript。你可能需要仔细研究Java实现的代码,才能找出可以进行的更改(就像我在上面的Javascript参考中做的一样)。 - jfriend00
1个回答

1
这是我使用的一种方法,可以让它正常运行,可能有点棘手,是由我在StackOverflow上找到的几个答案组合而成的代码。
我使用的技巧是关闭套接字,将其设置为NULL,然后重新创建并尝试连接。 它有助于清除缓冲区并以平稳的方式重新连接。
ackMessageTimeOut = new AckMessageTimeOut(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());
                        acknowledgeMessage(null);
                        if (socket != null) {
                            socket.close();
                            socket = null;
                            connectSocket(); // Custom method which creates the socket and tries to connect it.
                        }
                    } else if (args[0].toString().equalsIgnoreCase("true")) {
                        cancelTimer(); //cancel timer if emit ACK return true
                        Log.d("ACK_SOCKET", "AckWithTimeOut : " + args[0].toString());
                    }
                }
            }
        };

        socket.emit("sendMessage", message, ackMessageTimeOut); // You can apply it on whatever event you want.

AckMessageTimeOut类如下所示:
private class AckMessageTimeOut implements Ack {

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

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

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

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

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

        void callback(Object... args) {
            if (called)
                return;

            called = true;
            cancelTimer();
            call(args);
        }

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

        }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接