2012-05-02 4 views
1

Мы знаем, что в Java EE servlet/jsp клиент может получить один ответ HTTP для одного HTTP-запроса. Я хочу реализовать что-то, у которого неизвестная длина ответа HTTP. Я хочу, чтобы сервер продолжал толкать данные для клиента после того, как клиент отправил первый HTTP-запрос. В этом случае я не хочу использовать AJAX, потому что AJAX довольно тяжелый.Unknow length Http Response

Например, я хочу создать веб-страницу, которая может получить сообщение журнала с веб-сервера, сообщение журнала может быть отправлено веб-сервером, когда сообщение журнала создается из другого модуля (так что в этом случае временной интервал неизвестно, мы предполагаем, что регулярная проверка таймера здесь не перечитывается). Сообщение журнала добавляется к веб-браузеру, что означает, что веб-браузер не может обновиться, например:

Журнал 12:00 pm ..... Журнал 12:03 вечера ..... Журнал 12:04 вечера. .... . . .

Как я могу это сделать, отправив только один HTTP-запрос и всегда получая ответ http?


@dystroy

ли вы имеете в виду, что я могу очистить PrintWriter несколько раз (когда есть новые данные журнала) до конца doPost/doGet?

, пожалуйста, игнорируйте синтаксическую ошибку! Я не использовал IDE.

protected void doPost(HttpServletRequest req, HttpServletResponse resp){ 

    PrintWriter pw = resp.getWriter(); 

    pw.println("<html><body>Testing for the streaming.</body></html>"); 
    pw.flush(); 


    /* 
    The syntax could not be correct, please focus on logic. 
    This while loop check the log sent by web server is finised or not and flush the data to the 
    client, after that the javascript will change the content of the inner Html. Is the logic below 
    valid? 
    */ 
    while(!log.finish()){ 
     pw.println("document.setInnerHtml("+log.newLog()+")"); 
     pw.flush(); 
    } 

} 

ответ

0

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

Правильными решениями являются либо некоторые попытки потянуть с помощью ajax, либо использовать websockets, которые очень легкие и быстрые, но не поддерживаются всеми браузерами (см. http://caniuse.com/websockets).

О «тяжелом весе» ajax, обратите внимание, что стоимость по существу является одной из ответов на запрос http +. Если вы не запрашиваете время ожидания менее 100 мс и имеете обычные соединения, вы обнаружите, что ajax достаточно быстр (предпочитайте использование сервлетов через jsp). Просто не инкапсулируйте свой журнал в слишком тяжелый формат.

+0

Привет, я не могу добавить код здесь, не могли бы вы помочь мне проверить код выше? Является ли это похожим на то, что вы говорите. –

+0

Я не тестировал его, но ваш код кажется правильным. Вы попробовали это и возникли проблемы?Поскольку я пытаюсь объяснить, что этот подход работает, но не очень хорошо, особенно с плохой сетью или если вы прекратите писать в течение длительного времени. –

+0

Я попробую, когда я вернусь домой. Кстати, должен ли я установить соединение «Keep Alive», как это было предложено другим комментатором. –

0

Возможно, вам необходимо использовать keep-alive.

Это позволяет клиенту повторно использовать существующее соединение для постоянного чтения данных с сервера. Ниже, просто скопируйте пример из ссылки, указанной ниже.

try { 
    URL a = new URL(args[0]); 
    URLConnection urlc = a.openConnection(); 
    is = conn.getInputStream(); 
    int ret = 0; 
    while ((ret = is.read(buf)) > 0) { // here it try to read response using existing connection. 
     processBuf(buf); 
    } 
    // close the inputstream 
    is.close(); 
} catch (IOException e) { 
    try { 
     respCode = ((HttpURLConnection)conn).getResponseCode(); 
     es = ((HttpURLConnection)conn).getErrorStream(); 
     int ret = 0; 
     // read the response body 
     while ((ret = es.read(buf)) > 0) { 
      processBuf(buf); 
     } 
     // close the errorstream 
     es.close(); 
    } catch(IOException ex) { 
     // deal with the exception 
    } 
} 

Используйте технику, показанную выше для загрузки файла журнала.

Вот хорошее объяснение по этому вопросу: Persistent Connection


Другим вариантом является просто простым, рассмотреть вопрос о внесении Ajax Request.

+0

Спасибо за статью. Как я попытаюсь использовать одно и то же в сервлет/jsp? Я не могу связать статью с тем, как я могу достичь этого в servlet/jsp. Может дать мне больше подсказки? –