java - 当同一对象运行回调时重新创建对象的设计模式

标签 java websocket callback

这是我正在尝试做的事情的一个简单的玩具示例。

我有一个 WebSocket 类,它实现了方法 onClose()。当 Socket 关闭时,它会触发一个事件处理程序(lambda 函数)。

public class WebSocket {
  ICallback cb;

  public WebSocket(ICallback cb) {
      this.cb = cb;
      this.onClose(); // Simulating socket closing
  }

  public void onClose() {
    this.cb.handle();
  }

  @FunctionalInterface
  public static interface ICallback {
    public abstract void handle();
  }
}

在父类中,我创建了该类的一个新实例。当套接字关闭时,我必须重新创建此类的新实例。 (旧的无法使用)

这是我的实现

class Parent {
  static WebSocket socket;

  public static void main(String[] args) {
    Parent.createSocket();
  }

  public static void createSocket() {
    Parent.socket = new WebSocket(() -> { Parent.createSocket(); });
  }
}

此代码有效

但每当触发 onClose() 时,就会将一个新帧添加到堆栈中。如果运行足够长的时间并假设有许多错误导致套接字关闭,最终会导致 StackOverflowError。

<强> Running Example

在不增加堆栈大小的情况下重新创建 WebSocket 对象的最佳模式是什么?

运行一个连续检查套接字状态的线程是一种可行的方法吗? 即:

while(socket.isOpen()) {
 Thread.sleep(1000);
}
createSocket();

最佳答案

堆栈溢出的原因是您的回调永远不会完成 - 您只需创建一个新套接字并运行它,但旧套接字保持 Activity 状态。下一张也一样,依此类推。

因此,处理此问题的一种方法是同时创建套接字,为 onClose() 方法提供实际终止的方法。

您可以通过将实际创建提交给 ExecutorService 来做到这一点;单线程就可以了,因为毕竟您只希望在给定时间运行一个套接字。

class Parent {
    static WebSocket socket;
    // this is where the socket runs
    private static final ExecutorService EXECUTOR = Executors.newSingleThreadExecutor();

    public static void main(String[] args) {
        createSocket();
    }

    private static void createSocket() {
        Parent.socket = new WebSocket(() -> {
            EXECUTOR.submit(Parent::createSocket);
        });
    }
}

这样,当 onClose() 调用回调时,它会立即返回,并提交新 Web 套接字的创建。该创建尚未发生,因为执行器是单线程的,并且先前的套接字仍在该线程中运行。但一旦完成,就会执行下一次提交 - 即刚刚提交的创建。

顺便说一句,同时运行网络连接几乎总是一个好主意,因此主线程仍然可用于其他任务。

关于java - 当同一对象运行回调时重新创建对象的设计模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57518650/

相关文章:

java - 执行查询时出现ORA-12899错误

java - JSP: session 无法解析为类型

java - 使用 Chef 安装 Tomcat-8

java - 将 JaxRS REST 服务与 WebSocket 集成

php - 如何将 call_user_func 用于静态类方法?

java - 如何使用 Java 套接字检测数据丢失?

python - 调用 WebSocket.close 时现有等待会发生什么

javascript - WebSocket/Node.js 帮助 : Can't establish a connection to wss://domain:8080 - NOT browser specific

c++ - 在 C++ 中使用 RegisterWaitForSingleObject 将参数传递给回调函数

javascript - 在回调中重用变量/对象