如何将数据推送到jsp而不是每2秒请求一次?

时间:2011-12-25 16:52:34

标签: java javascript spring google-maps-api-3 server-push

我希望每2秒将数据推送到jsp,而客户端请求它 我在这里使用Spring和Hibernate 我正在显示谷歌地图标记,我想通过从数据库获取数据每2秒更新标记位置,但是我已经从数据库获取数据每2秒,但我无法将数据推送到此JSP。

   @Scheduled(fixedRate = 2000)
   public void getData(){
                    // TODO Auto-generated method stub
                    DeviceDetails deviceDetails = realTimeDataDAO.getDeviceDetails(deviceId);
                    System.out.println(deviceDetails);
                }

每2秒钟后我必须显示一些数据。谁能告诉我怎么做?

任何人都知道Comet Ajax Push技术,它会在这种情况下有效吗?

10 个答案:

答案 0 :(得分:5)

你有很多选择。

轮询 - 正如其他答案中所提到的,您可以简单地让客户端中的javascript每2秒轮询一次服务器。这是一种非常常见的方法,很简单,适用于大多数浏览器。虽然不像其他一些方法正确设置那样可扩展,但它仍然可以轻松扩展到适度的卷(可能比你拥有的用户多!)。

长轮询 - 也称为Comet,这本质上是一个长期存在的请求。具体取决于您的应用服务器。请参阅此处了解Tomcat:http://wiki.apache.org/tomcat/WhatIsComet或Jetty捆绑了一些示例。

HTML 5解决方案,而网络传统上是基于请求的响应 - 基于事件的处理是HTML 5规范的一部分。因为事件似乎只有一种方式(服务器 - >客户端)考虑使用事件源。请参阅:http://www.html5rocks.com/en/tutorials/eventsource/basics/或Jetty示例。这里的注意事项是只有现代浏览器和一些应用服务器支持这些方法 - 例如Apache本身不支持websockets。

总而言之 - 我的直觉是你的需求和简单的投票方法很好 - 最初不要过于担心性能问题。

如果你想要处于最前沿,学习新东西,你可以控制你的应用服务器和框架,那么我就会采用HTML 5方法。

彗星是这两者之间的中间人。

答案 1 :(得分:2)

最好的方法是让客户端每2秒发送一次请求,然后显示新数据。

由于你使用HTTP我假设你在客户端使用javascript,所以你需要在你的javascript中每2秒触发一次计时器,然后让javascript对服务器执行ajax调用以获取它可以的数据然后显示。

答案 2 :(得分:2)

使用Spring最好的办法是将调度查询的结果存储到内存中的bean中,然后让另一个请求范围bean将该结果存储在可通过Web访问的方法中,并将其作为文本返回(或JSON )。或者,您可以在每次请求更新时查询数据库。

然后,您可以从页面发出定时异步请求(您可能希望使用YUI Connection Manager),阅读响应并使用google.maps.Map中的panTo方法更新您的地图位置。

如您所见,该解决方案分为Java和JavaScript部分。

对于Java端,您必须创建一个控制器来执行对数据库的查询(或者更好,将该任务委托给另一个层)并将结果作为JSON返回,您可以使用http://spring-json.sourceforge.net/。它在Spring中有点复杂,所以你可能想要创建一个返回数据的简单servlet。

对于Javascript方面,一旦你有一个返回JSON数据的工作端点,使用YUI Connection Managergoogle maps api

function update(){
    var callback = {
        success: function (o) {
            var response = YAHOO.lang.JSON.parse(o.responseText);
            map.panTo({lat: response.lat, lng: response.longi}); // map is the google.maps.Map representing your map
        },
        failure: function (o) {

        }
    }
    var sUrl = '/getData.htm'; // This is the request mapping for your bean
    YAHOO.util.Connect.asyncRequest('GET', sUrl,callback);
}

function init(){
    setTimeout("update()", 2000);
}

答案 3 :(得分:1)

尝试TimerTaskThreadExecutor(查看预定的实施方案)。

答案 4 :(得分:1)

好吧,如果您想在Web应用程序中实现上述解决方案,我不确定,但我认为您不能这样做。 HTTP是一种请求/响应协议,当服务器完成发送一个响应时,它无法自行发送新的响应。简而言之:来自客户端的一个请求 - 来自服务器的一个响应。

我认为您应该使用AJAX(异步Javascript请求),以便每2秒向服务器请求一个新数据,并在必要时更新DOM(网站HTML标记结构)。

答案 5 :(得分:1)

我对WebSockets有很好的经验。服务器和浏览器之间非常快速,低开销的双向协议。不确定你的后端是什么,但Jetty非常支持它。只需在后端有一个计时器进程,它将迭代所有活动的WebSockets会话并推送更新。网上有很多关于如何使用Websockets的例子。

要记住的事情:

  • 所有浏览器都不支持WebSockets(Chrome和Safari似乎是最受支持的)
  • WebSockets流量不会遍历所有代理

根据您的要求,可能会或可能不会接受。

有一些像Atmosphere这样的项目试图在websockets支持中抽象浏览器/服务器差异,并优雅地回退到Comet。值得一看。

答案 6 :(得分:0)

//Initialize this somewhere
ScheduledExecutorService exe = Executors.newScheduledThreadPool(1);

exe.scheduleWithFixedDelay(new Runnable() {

    @Override
    public void run() {
        //The executor service tries to run 2 seconds after it last finished
        //If you code takes 1 second to run this will effectively run every 3 seconds 
    }
}, 0, //this is the initial delay
2, //this is the consecutive delay
TimeUnit.SECONDS);

exe.scheduleAtFixedRate(new Runnable() {

    @Override
    public void run() {
        //The executor service tries to run this every 2 seconds
        //If you code takes 1 second to run this will still run evey 2 seconds
    }
}, 0, //this is the initial delay
2, //this is the period it tries to run in
TimeUnit.SECONDS);

答案 7 :(得分:0)

您需要每2秒从服务器向客户端发送数据。并且您已经知道如何在服务器端每2秒收集一次数据。

如果这就是您所需要的,那么“Ajax流媒体”将对您有所帮助。这是在客户端。从服务器端每2秒钟,您需要写入数据并冲洗它。

搜索这个术语会给你很多例子。但请记住,所有现代浏览器都将使用一种方法,所有IE浏览器都将使用IFrame方法来实现流式传输。

在第一种情况下,您需要发出XHR请求并查看响应并进行处理。

以下是一些例子:(我没时间完全了解它们)

http://ajaxpatterns.org/HTTP_Streaming

http://developers.cogentrts.com:8080/DH_ajax_1.asp

答案 8 :(得分:0)

你可以使用ajax调用。 因为您可以从Javascript编写代码,每2秒发送一次请求,但为此,您的服务器应该快速响应此类请求。

嗯,我想这会对你有帮助。

答案 9 :(得分:-1)

如果您的服务器拥有超过1000个用户,那么您的应用程序服务器将失败。我建议您仅使用Jetty Server支持的非阻塞输入输出方法来托管为此目的而发出的请求,并将普通的EE服务器用于其他应用程序。