6

I want to push the data to the jsp for every 2 seconds, with out client requesting it.
I am using Spring with Hibernate here.
I am displaying google maps marker, and I want to update the marker location for every 2 seconds by getting the data from database, however I have done getting the data from database for every 2 seconds, but I am unable to push that data to this jsp.

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

I have to display some data after every 2 seconds. Can anyone tell me how to do that?

any one knows about Comet Ajax Push technology, will it work in this scenario?

gnat
  • 6,213
  • 108
  • 53
  • 73
Ramesh Kotha
  • 8,266
  • 17
  • 66
  • 90
  • Just answered - it would be helpful if you said what app server you are using - or if you are flexible on which to choose. – Pablojim Jan 09 '12 at 19:51

10 Answers10

5

You have a number of choices.

Polling - as mentioned in other answers you could simply have javascript in the client constantly poll the server every 2 seconds. This is a very common approach, is simple and will work in the large majority browsers. While not as scaleable as some other approaches setup correctly this should still be able to easily scale to moderate volumes (probably more users than you'll have!).

Long polling - Also known as Comet this is essentially a long lived request. The implementation of this will vary depending on your app server. see here for Tomcat: http://wiki.apache.org/tomcat/WhatIsComet or Jetty bundles some examples.

HTML 5 solutions while the web is traditionally request response based - event based processing is part of the HTML 5 spec. As you events seem to be only one way (server -> client) Consider using Event sources. See: http://www.html5rocks.com/en/tutorials/eventsource/basics/ or again the Jetty examples. Caveats here are that only modern browsers and some app servers support these methods - e.g. Apache doesn't natively support websockets.

So to sum up - my gut feeling is that your needs and for simplicity a polling approach is fine - don't worry too much initially about performance issues.

If you want to be on the cutting edge, learn new thing and you have control over your app server and frameworks then I'd go for the HTML 5 approach.

Comet is kind of a half way house between these two.

Pablojim
  • 8,542
  • 8
  • 45
  • 69
  • Hi Pablojim, i am using Tomcat as server with spring + hibernate + google maps api v3. i don't have any knowledge regarding HTML 5, can u guide me. – Ramesh Kotha Jan 10 '12 at 14:16
2

The best way to do it is to have the client send an new request every 2 second, and then display the new data.

Since you use HTTP i assume you use javascript on the client side, so you need a timer in your javascript which fire every 2 second, and then let the javascript perform an ajax call to the server to get the data which it can then display.

MTilsted
  • 5,425
  • 9
  • 44
  • 76
2

Your best bet with Spring is to store the results of the scheduled query into a bean in memory, then have another request-scope bean get that stored result in a method that is web accessible, and return it as text (or JSON). Alternatively you could query the DB everytime an update is requested.

Then, you can make a timed async request from your page (You may want to use YUI Connection Manager for that), read the response and use the panTo method from google.maps.Map to update your map location.

As you can see, the solution is split in a Java and a JavaScript portion.

For the Java side, you must create a controller that performs the query to the database (or better yet, delegates that task to another layer) and returns the results as JSON, you can use http://spring-json.sourceforge.net/ for that. It's a bit complex in Spring so you might want to instead create a simple servlet that returns the data.

For the Javascript side, once you have a working endpoint that returns the JSON data, using YUI Connection Manager and the google 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);
}
Slash
  • 496
  • 2
  • 8
  • thank you very much @Slash, but is there any other way other than YUI, becoz i don't have any knowledge on that. – Ramesh Kotha Jan 11 '12 at 21:14
  • @RameshK do you have knowledge of a JavaScript framework? because I don't think you can do this using Spring alone; Spring is server side so you can schedule tasks to be executed but those will only happen on the server as far as I know. This code for example uses JQuery instead of YUI: http://blog.springsource.org/2010/01/25/ajax-simplifications-in-spring-3-0/ – Slash Jan 13 '12 at 13:19
  • I suggest you try out the YUI solution, it's pretty easy to set up (Just add the yui js files to your page, or load them directly from the yahoo website: http://developer.yahoo.com/yui/articles/hosting/?connectioncore&MIN . Then you can use the YAHOO.util.connect function – Slash Jan 13 '12 at 20:36
1

Try a TimerTask or ThreadExecutor (look at the scheduled implementation).

duffymo
  • 305,152
  • 44
  • 369
  • 561
  • http://www.java2s.com/Code/Java/Development-Class/UsejavautilTimertoscheduleatasktoexecuteonce5secondshavepassed.htm – duffymo Dec 29 '11 at 15:57
  • I don't think this really helps as it doesn't tackle displaying the data to the user – Edd Jan 07 '12 at 19:07
1

Well, if you want to implement above solution in web application I am not sure but I think you cannot do it this way. HTTP is a request/response protocol and when the server finish sending one response it cannot initiate on its own sending a new response. In short words: one request from client - one response from server.

I think that you should use AJAX (asynchronous Javascript requests) so as to ask server every 2 second for a new data and if necessary update the DOM (website HTML tags structure).

M. Hryszczyk
  • 1,184
  • 10
  • 11
  • i think its not good way of sending the request through ajax, because every time we need to hit the same database table. so if we write a java daemon thread which runs background and send the data to the UI continuously. – Ramesh Kotha Dec 26 '11 at 04:55
  • It might look like a bad idea but it is a common solution in a web applications :) – M. Hryszczyk Dec 26 '11 at 09:12
  • @M.Hryszczyk you would have been correct perhaps a decade ago. The original spec for HTTP is as you say, but its prevalence and the common requirement for push capabilities has led to *dozens* of comet like server-push streaming implementations on nearly every server platform. Server-Sent-Events and Web Sockets will only continue this evolution further, also both cleverly crafted to coexist on http/port 80. – BenSwayne Jan 11 '12 at 16:44
1

I have had good experience with WebSockets. Very fast, low overhead bi-directional protocol between server and browser. Not sure what's your backend but Jetty supports it very well. Just have a timer process on the backend which would iterate over all active WebSockets sessions and push updates. There are plenty example on the net of how to use Websockets.

Things to keep in mind:

  • WebSockets not supported by all browsers (Chrome and Safari seems to be the best supported)
  • WebSockets traffic doesn't traverse all proxies

Depending on your requirements it might or might not be acceptable.

There are some projects like Atmosphere which tries to abstract browser/server differences in websockets support with graceful fallback to Comet. It might worth to look at.

maximdim
  • 8,041
  • 3
  • 33
  • 48
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);
patheros
  • 279
  • 1
  • 2
  • 11
  • thanks dude, can u please tell me how to update the jsp page. after running this method for every 2 seconds, i have to get the data and push to jsp – Ramesh Kotha Jan 08 '12 at 17:35
  • ajax and commet should work. You'd have to find either find or write a Java server component that you can then push the data to and also a JavaScript client component that will "receive" the data in the user's browser. – patheros Jan 08 '12 at 19:45
  • The hardest part will be writing custom JavaScript for the client that updates the parts of the page you want to. You won't be able to use any JSP tags as they are only evaluated when the page first loads. – patheros Jan 08 '12 at 19:50
  • I have not used Comet or JavaScript enough to feel comfortable giving you a custom example. I did however find this example that looks to be the basics for what you might do. [link]http://blogs.oracle.com/swchan/entry/a_simple_comet_example_hidden In it they have a shared counter that anyone viewing a website can increment and then everyone sees it. For your problem you'd have to call the "notify()" method every 2 seconds and then instead of passing along the count pass along the location. Finally in the updateCount() method in java script you'd have to update the map. I hope that helps. – patheros Jan 08 '12 at 21:13
0

You need to send the data from server to client for every 2 secs. And already you know how to gather the data for every 2 seconds at the server side.

If this is all you need, the "Ajax streaming" will help you. This is on the client side. From server side for every 2 seconds you need to write the data and flush it.

Searching for this term will give you lot of examples. But remember all modern browsers will use one approach and all IE browsers will use IFrame approach to implement streaming.

In the first case, you need to make XHR request and peek the response and process it.

Here are a few examples: (I didt have time to go through them completely)

http://ajaxpatterns.org/HTTP_Streaming

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

Pragalathan M
  • 1,673
  • 1
  • 14
  • 19
0

U can use ajax call. As you can write code from Javascript that will send the request for every 2 seconds,but for this your server should be quick responsive for this type of request.

Well I guess this will help you.

Sam....
  • 165
  • 2
  • 19
-1

If your server gets more than 1000 users then your application server will fail. I recommend you use NON Blocking Input Output methods supported using Jetty Server only to host the requests made for this purpose and use your normal EE Server for other applications.

Acn
  • 1,010
  • 2
  • 11
  • 22
  • I think this is going out of track – Avil Jan 11 '12 at 04:39
  • @BigFatPig don't post answers for which you don't have a reliable source of information. I regularly test 20,000 clients on a single server with [WebSync](http://www.frozenmountain.com/websync/ "WebSync Comet Server for IIS") and have server clusters regularly seeing 4000-6000 simultaneous real-world users. – BenSwayne Jan 11 '12 at 16:49