Как отправить данные в JSP без запроса каждые 2 секунды? - PullRequest
5 голосов
/ 25 декабря 2011

Я хочу отправлять данные в jsp каждые 2 секунды без запроса клиента.
Я использую Spring с Hibernate здесь.
Я показываю маркер карт Google, и я хочу обновлять местоположение маркера каждые 2 секунды, получая данные из базы данных, однако я завершил получение данных из базы данных каждые 2 секунды, но я не могу отправить эти данные в эту JSP.

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

Мне нужно отображать некоторые данные через каждые 2 секунды. Может кто-нибудь сказать мне, как это сделать?

Кто-нибудь знает о Комета Технология Ajax Push, будет ли она работать в этом сценарии?

Ответы [ 10 ]

5 голосов
/ 09 января 2012

У вас есть несколько вариантов.

Опрос - как уже упоминалось в других ответах, вы могли бы просто иметь 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 изначально не поддерживает веб-сокеты.

Итак, подведем итог - мое внутреннее чувство заключается в том, что ваши потребности и, для простоты, подход для опроса - это нормально - не стоит слишком сильно беспокоиться о проблемах производительности.

Если вы хотите быть на переднем крае, узнавать что-то новое, и у вас есть контроль над сервером приложений и фреймворками, тогда я бы пошел на подход HTML 5.

Комета - своего рода дом на полпути между этими двумя.

2 голосов
/ 10 января 2012

Лучше всего в Spring сохранять результаты запланированного запроса в bean-компоненте в памяти, а затем иметь другой bean-объект запроса, получивший сохраненный результат в методе, доступном через Интернет, и вернуть его в виде текста (или JSON).).В качестве альтернативы вы можете запрашивать БД каждый раз, когда запрашивается обновление.

Затем вы можете сделать синхронизированный асинхронный запрос со своей страницы (для этого вы можете использовать YUI Connection Manager), прочитать ответ и использовать panToметод из google.maps.Map для обновления местоположения на карте.

Как видите, решение разделено на части Java и JavaScript.

Для стороны Java необходимо создатьконтроллер, который выполняет запрос к базе данных (или, что еще лучше, делегирует эту задачу другому уровню) и возвращает результаты в виде JSON, для этого можно использовать http://spring -json.sourceforge.net / .Это немного сложно в Spring, поэтому вы можете вместо этого создать простой сервлет, который возвращает данные.

Для стороны Javascript, когда у вас есть рабочая конечная точка, которая возвращает данные JSON, используя YUI ConnectionДиспетчер и 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);
}
2 голосов
/ 26 декабря 2011

Лучший способ сделать это - заставить клиента отправлять запрос новый каждые 2 секунды, а затем отображать новые данные.

Поскольку вы используете HTTP, я предполагаю, что вы используете javascript на стороне клиента, поэтому вам нужен таймер в вашем javascript, который срабатывает каждые 2 секунды, а затем позволяет javascript выполнять ajax-вызов к серверу для получения данных.который он может затем отобразить.

1 голос
/ 14 января 2012

У меня был хороший опыт работы с WebSockets. Очень быстрый двунаправленный протокол с низкими издержками между сервером и браузером. Не уверен, какой у тебя бэкэнд, но Jetty очень хорошо это поддерживает. Просто используйте процесс таймера на бэкэнде, который будет перебирать все активные сеансы WebSockets и отправлять обновления. В сети есть множество примеров использования Websockets.

Что нужно иметь в виду:

  • WebSockets, поддерживаемые не всеми браузерами (Chrome и Safari, кажется, поддерживаются лучше всего)
  • Трафик WebSockets не пересекает все прокси

В зависимости от ваших требований это может быть или не быть приемлемым.

Есть несколько проектов, таких как Atmosphere , которые пытаются абстрагироваться от различий между браузерами и серверами в поддержке веб-сокетов с постепенным отступлением от Comet. Возможно, стоит посмотреть.

1 голос
/ 26 декабря 2011

Ну, если вы хотите реализовать вышеуказанное решение в веб-приложении, я не уверен, но думаю, что вы не можете сделать это таким образом.HTTP - это протокол запроса / ответа, и когда сервер заканчивает отправку одного ответа, он не может самостоятельно инициировать отправку нового ответа.Вкратце: один запрос от клиента - один ответ от сервера.

Я думаю, что вам следует использовать AJAX (асинхронные запросы Javascript), чтобы каждые две секунды запрашивать у сервера новые данные и при необходимости обновлять DOM(структура HTML-тегов сайта).

1 голос
/ 25 декабря 2011

Попробуйте TimerTask или ThreadExecutor (посмотрите на запланированную реализацию).

0 голосов
/ 09 января 2012

U может использовать вызов ajax. Как вы можете написать код из Javascript, который будет отправлять запрос каждые 2 секунды, но для этого ваш сервер должен быстро реагировать на этот тип запроса.

Ну, я думаю, это тебе поможет.

0 голосов
/ 09 января 2012

Если ваш сервер получает более 1000 пользователей, то ваш сервер приложений не будет работать Я рекомендую использовать методы NON Blocking Input Output, поддерживаемые Jetty Server, только для размещения запросов, сделанных для этой цели, и использовать обычный EE Server для других приложений.

0 голосов
/ 09 января 2012

Вам необходимо отправлять данные с сервера клиенту каждые 2 секунды. И вы уже знаете, как собирать данные каждые 2 секунды на стороне сервера.

Если это все, что вам нужно, вам поможет потоковая передача Ajax. Это на стороне клиента. Со стороны сервера каждые 2 секунды вам нужно записывать данные и очищать их.

Поиск по этому термину даст вам множество примеров. Но помните, что все современные браузеры будут использовать один подход, и все браузеры IE будут использовать подход IFrame для реализации потоковой передачи.

В первом случае вам нужно сделать запрос XHR, посмотреть ответ и обработать его.

Вот несколько примеров: (у меня не было времени, чтобы пройти их полностью)

http://ajaxpatterns.org/HTTP_Streaming

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

0 голосов
/ 08 января 2012
//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);
...