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

Posted

技术标签:

【中文标题】断开连接/错误时清除 socket.io 缓冲区【英文标题】:Clear socket.io buffer on disconnect/error 【发布时间】:2016-04-04 21:17:28 【问题描述】:

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

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

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

【问题讨论】:

相关信息:***.com/questions/32131629/…. 感谢您的帮助。我是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> sendBuffer = new LinkedList>();只有具有 sendBuffer 的公共方法 public Emitter emit(final String event, final Object... args) //很多代码(这段代码正在修改一些私有类变量,所以不能覆盖。 if (Socket.this.connected) Socket.this.packet(packet); else Socket.this.sendBuffer.add(packet);在这种情况下,您能建议清除 sendBuffer 吗?我还尝试克隆此存储库并将其添加为模块,但它也有很多其他依赖项,因此会出现很多编译错误。 如果您使用 Java 编程,我将无能为力。您的问题没有标记 Java(我只是在您的问题中添加了该标记),所以我错误地认为您使用的是 javascript。您可能必须研究 Java 实现的代码,以弄清楚您可以进行哪些更改(就像我在上面的 Javascript 参考中所做的那样)。 【参考方案1】:

这是一种对我有用的方法,它可能有点棘手,是的,这里的代码是我在 *** 上找到的几个答案的组合。

我使用的技巧是关闭套接字,使其为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) 

        
    

【讨论】:

以上是关于断开连接/错误时清除 socket.io 缓冲区的主要内容,如果未能解决你的问题,请参考以下文章

Socket.io断开事件错误地为其他用户触发,然后再次连接

断开连接时销毁socket.io连接

socket.io 在空闲时断开客户端的连接

刷新时Socket.io断开连接?

socket.io 服务器在注册客户端断开连接时非常延迟

Socket.io 不会在断开连接时向房间发送消息