Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 是否建议使用服务器发送的事件通过连续查询数据库来推送通知?_Java_Spring Boot_Websocket_Push Notification_Server Sent Events - Fatal编程技术网

Java 是否建议使用服务器发送的事件通过连续查询数据库来推送通知?

Java 是否建议使用服务器发送的事件通过连续查询数据库来推送通知?,java,spring-boot,websocket,push-notification,server-sent-events,Java,Spring Boot,Websocket,Push Notification,Server Sent Events,我希望通过不断查询数据库,将实时通知(登录用户的DTO对象)推送到客户端。我使用服务器端事件来实现同样的目的。然而,在实现这一目标方面,我面临的问题很少。我正在javascript中使用EventSourceAPI 在无限循环中轮询 因为我的数据在数据库中,所以我经常需要运行查询来获取最新的条目,并使用executor.execute(()->{while(true){emitter.send(data)}}Thread.sleep(5000)),直到用户注销。(a) 在无限循环中查询数据库和(

我希望通过不断查询数据库,将实时通知(登录用户的DTO对象)推送到客户端。我使用服务器端事件来实现同样的目的。然而,在实现这一目标方面,我面临的问题很少。我正在javascript中使用EventSourceAPI

  • 在无限循环中轮询
  • 因为我的数据在数据库中,所以我经常需要运行查询来获取最新的条目,并使用
    executor.execute(()->{while(true){emitter.send(data)}}Thread.sleep(5000))
    ,直到用户注销。(a) 在无限循环中查询数据库和(b)创建新的ExecutorService对象会导致JDBC池耗尽异常,并最终冻结应用程序

  • 使用SPRING BOOT@Scheduled 这也不起作用,因为我需要登录用户_id,而我无法使用
    SpringContextHolder.getAuthentication
    在@Scheduled annotated方法中获取该id,因为此Cron不是由用户启动的
  • 我选择SSE而不是WebSockets是不是做错了,或者有没有办法实现这个特定用例的服务器端


    请帮助/指导我。

    如果您想将事件推送到您的客户机,最好在后端也有事件概念,而不是轮询。如果您想轮询数据库,最好让客户机来做。SSE或websocket在该决定中并不重要

    CDI活动可能是适合您需要的解决方案

    • 创建一个
      EntityForLoggedInUsersChanged
      事件类
    • 在您的服务中插入一个
      事件
      ,该事件改变与loggedin用户相关的实体。当他们这样做时触发事件
    • 创建一个服务,该服务将观察这些事件,构建您想要推送的dto,获得相关用户的频道,然后推送它

      • 令人惊讶的是,这是一个有效的模式

        与让数据库发送推送通知相比,每5秒轮询一次可能会占用更少的总体资源(即使假设数据库支持这一点)

        与让客户端每5秒进行一次AJAX调用(每次都需要设置一个DB连接)相比,它可能更高效(代价是保持SSE套接字始终打开)

        创建新的ExecutorService对象会导致JDBC池耗尽异常,并最终冻结应用程序

        池耗尽是因为只有一个用户,每5秒轮询一次吗?还是因为有很多用户,每个用户都保持数据库连接打开

        如果是后者,请使池足够大,以支持您希望允许的最大数量的同时连接的用户

        如果是前者,您要么在轮询后释放资源,然后再进行5000ms睡眠,要么在循环外部打开资源一次,然后找到一种方法在无限循环内重新运行查询

        (很抱歉,我不熟悉
        ExecutorService
        Spring
        ;这可能是查询数据库的抽象层次太高,需要使用较低层次的函数?)


        顺便说一句,SSE和Web套接字在这里没有什么区别。Web套接字为您提供了一个更复杂的协议,作为交换,它是一个双向连接,而不是单向连接,但其他一切基本相同。也就是说,在客户端和web服务之间仍然有一个专用套接字,并且仍然有一个无限循环轮询数据库。

        与上面的一点相矛盾的是,对于websocket,我不需要继续循环我的数据库。无论何时发生事件(比如创建注释/通知),在我的应用程序代码中,我都可以通过专用websocket频道广播消息。EventSource没有通道的概念。@VipulKumar如果您可以在websocket服务器中发生事件时收到通知(然后广播),那么您也可以为EventSource执行此操作。(顺便说一句,您可以指定
        事件
        标题来获取通道的概念,但我通常建议不要使用它,而是在一个消息处理程序中处理所有内容。例如,查看此人得出相同结论的地方。)Darren Cook感谢您的输入。但是,我们仍然必须不断循环/轮询数据库。