jersey-2.0 - Grizzley 服务器关闭时,Jersey 资源 @PreDestroy 不会被调用

标签 jersey-2.0 server-sent-events grizzly

我正在运行一个简单的 Jersey/Grizzly HTTP 服务器,其中包含处理服务器发送的事件的资源。

该资源需要手动处理 Timer 实例,以将一些保持事件的数据发送到所有连接的 SSE 客户端,因此我使用 @PostConstruct @PreDestroy 注解来构造和取消该计时器(及其后台线程)。

该应用程序是一个简单的控制台应用程序,没有嵌入到 Tomcat 等任何容器环境中。启动 Web 服务器后,它会等待一个简单的 System.in.read() 并通过调用 shutdownNow() 再次关闭服务器。在 Grizzly HTTP 服务器实例上。

当连接到SSE资源时,资源类被实例化并启动计时器。与服务器断开连接后,短暂延迟后资源再次被销毁,一切正常。

但由于 SSE 资源的性质,客户端可能会无休止地连接,从而在内部保留资源实例。

如果我现在在客户端连接时尝试通过调用 shutdownNow() 来关闭服务器,服务器实例会正确关闭,但不会调用任何 @PreDestroy活跃资源的方法。这会导致我的带有 Timer 实例的资源保留下来,并且由于计时器仍然处于事件状态,因此即使 HTTP 服务器已经关闭,这也会使 java 进程保持运行。

有没有办法检索所有当前事件的资源实例,以便我可以在关闭 HTTP 服务器之前手动调用它们各自的销毁方法?或者这可能是资源实例管理中的错误Grizzly 服务器的?

使用的版本是:

  • jersey-container-grizzly2-http:2.27
  • grizzly-http-server:2.4.0(上面的依赖项)

这是代码的精简版本:

public class ServerSentEventResource {
    @Context
    private Sse sse;
    private volatile SseBroadcaster broadcaster;
    private final Timer timer = new Timer();

    @PostConstruct
    public void init() {
        broadcaster = sse.newBroadcaster();
        final TimerTask task = new TimerTask() {
            // ...
        };
        timer.scheduleAtFixedRate(task, 0, 1000);
    }

    @PreDestroy
    public void destroy() {
        timer.cancel();
        broadcaster.close();
    }

    @GET
    @Produces(SseFeature.SERVER_SENT_EVENTS)
    public void get(@Context final SseEventSink eventSink) {
        broadcaster.register(eventSink);
    }
}

public static void main(final String[] args) {
    ResourceConfig resourceConfig = new ResourceConfig();
    resourceConfig.register(ServerSentEventResource.class);

    HttpServer server = GrizzlyHttpServerFactory.createHttpServer(URI.create("0.0.0.0:8888"), resourceConfig);
    System.in.read();
    server.shutdownNow();

    // At this point there is still the resource instance around, keeping the timer running, thus keeping the JVM running :(
}

最佳答案

我也遇到了同样的问题。我能够通过在实际关闭服务器之前删除默认网络监听器来解决该问题...

httpServer.removeListener("grizzly");

关于jersey-2.0 - Grizzley 服务器关闭时,Jersey 资源 @PreDestroy 不会被调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53067164/

相关文章:

java - 问题 : java. lang.UnsupportedClassVersionError: org/glassfish/jersey/servlet/ServletContainer

java - Jersey 2.0 - Glassfish 4 Actor 异常

asp.net - 为什么代码会被 ASP 触发一次 :ImageButton Click not Triggered

php - 服务器发送的事件有效,但时间延迟很大

java - 所有带@PathParam 的 Jersey 路线返回 404

jersey - 如何启用 MultiPartFeature?

jax-rs - 将 InboundJaxrsResponse 转换为 json 字符串

python - CGIHTTPServer 上带有 Python cgi 脚本的 HTML5 服务器发送事件

java - 在 Grizzly 中配置 session cookie 名称

java - 在 Jersey 测试调用上设置查询参数