V tomto článku si ukážeme možnosti technológie nazvanej server push. Táto technológia podporovaná Servlet API je však mizerne podporovaná najpoužívanejšími prehliadačmi. Preto som vážne premýšľal či tento článok vôbec napísať. Nakoniec som sa však rozhodol pre napísanie, pretože tento seriál je o servletoch ako takých. Podpora v prehliadačoch je však dôležitá, inak by nemalo zmysel sa servletmi vôbec zaoberať. V súvislosti s technológiou server push však nejde ani tak o podporu nejakých špecifických servlet funkcií (pretože to je vec web servera), ale skôr o podporu určitého content type.

Doteraz sme vždy po odoslaní požiadavky na servlet získali odpoveď vo forme jedinej stránky, ktorá mohla obsahovať text alebo grafiku, respektíve akýkoľvek súbor (niekedy sme mohli obdržať prázdnu stránku alebo stránku plnú obsažného chybového výpisu; pravda, to je iná kapitola životného cyklu servletu). Získali sme teda jednu stránku s konkrétnym content type. Technológia push však umožňuje poslať na základe jednej požiadavky ako odpoveď niekoľko stránok za sebou, pričom každá môže mať vlastný content type.

Je to vlastne opak technológie, ktorú môžeme nazvať ako client pull, pri ktorej je na klientovi, aby získaval jednotlivé stránky zo servera v pravidelných intervaloch. Konečný výsledok je síce pre užívateľa rovnaký, ale implementačné detaily ako aj vhodnosť použitia v konkrétnej situácii, sú úplne odlišné.

Pri technológii server push zostáva spojenie medzi serverom a klientom otvorené a uzatvorí sa až po odoslaní poslednej stránky. Tento fakt umožňuje serveru pružne reagovať a posielať postupne jednotlivé stránky, respektíve aktualizácie jednej stránky. Server push technológia je vhodná pre stránky, ktoré potrebujú častú aktualizáciu, alebo pre stránky vyžadujúce nepravidelnú serverom riadenú aktualizáciu (napríklad rôzne burzové údaje). Ako som spomenul, táto technológia nie je zatiaľ podporovaná prehliadačmi a problém môže vzniknúť aj s maximálnym počtom súčasne otvorených konekcií.

Pri technike pravidelných klientských požiadaviek je konekcia na server ukončená po každej stránke, čo znamená, že zodpovednosť za aktualizáciu stránky je na klientovi. Klient na to používa záhlavie Refresh, ktoré môže byť nastavené prostredníctvom servleta. Táto technológia je preto vhodná skôr na pravidelné updaty existujúcej stránky.

Vytvoríme si príklad na ukážku možností technológie server push. Pôjde o servlet, ktorý spustí odpočítavanie, na konci ktorého zobrazí obrázok. Servlet začne posielať sériu stránok od 3 po 1. Každá stránka nahradí pôvodnú. Keď odpočítavanie skončí na nule, servlet pošle obrázok. Servlet využíva triedu MultipartResponse. Bohužiaľ nemám možnosť ukázať vám servlet v akcii, môžem vám ponúknuť iba výsledok s tým, že žiadny z bežných browserov nie je v súčasnosti schopný obrázok zobraziť v jeho skutočnej podobe. Najlepší výsledok som získal s prehliadačom Opera 7.0, ktorý jednotlivé odpovede spracovával a zobrazoval časovo správne, to znamená každé tri sekundy. Čo sa však týka obrázka na záver, ten zobraziť nedokázal.

CountDownServlet.java:

import java.awt.*;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class CountDownServlet extends HttpServlet {
 public void doGet
        (HttpServletRequest req, HttpServletResponse res)
                      throws ServletException, IOException {
  ServletOutputStream out = res.getOutputStream();
  // pripravíme si multipart response objekt
  MultipartResponse multi = new MultipartResponse(res);
  // spustíme countdown, môžete si nastaviť vlastné hodnoty
  for (int i = 3; i > 0; i–) {
   multi.startResponse(„text/plain“);
   out.println(i + „…“);
   multi.endResponse();
   try { Thread.sleep(3000); }
   catch (InterruptedException e) { }
  }
  // na záver pošleme obrázok
  multi.startResponse(„image/gif“);
  try {
   ServeFile.returnFile(req.getPathTranslated(), out);
  }
  catch (FileNotFoundException e) {
   throw new ServletException(„Súbor nenájdený: “ +
                                            e.getMessage());
  }
  // ukončíme multipart response
  multi.finish();
 }
}

MultipartResponse.java:

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class MultipartResponse {
 HttpServletResponse res;
 ServletOutputStream out;
 boolean endedLastResponse = true;
 public MultipartResponse(HttpServletResponse response)
                                      throws IOException {
  // uložíme objekty response a output stream
  res = response;
  out = res.getOutputStream();
  // nastavíme potrebný content type
  res.setContentType(„multipart/mixed-replace“);
 }
 public void startResponse(String contentType)
                                      throws IOException {
  // ak je to nutné ukončíme posielanie odpovedí
  if (!endedLastResponse) {
   endResponse();
  }
  // začneme novú sekvenciu posielania odpovedí
  out.println(„Content-Type: “ + contentType);
  out.println();
  endedLastResponse = false;
 }
 public void endResponse() throws IOException {
  // ukončíme poslednú odpoveď a zavoláme flush()
  out.println();
  out.println(„–Koniec“);
  out.println();
  out.flush();
  endedLastResponse = true;
 }
 public void finish() throws IOException {
  out.println(„–Koniec–„);
  out.flush();
 }
}

Na začiatku vytvoríme objekt pomocnej triedy MultipartResponse, ktorému ako parameter predáme objekt HttpServletResponse. Ten bude následne použitý na získanie výstupného prúdu a na nastavenie správneho content type. Nasleduje vytváranie novej stránky zavolaním metódy startResponse() a zapisovaním na štandardný výstup. Zavolanie metódy endResponse() zabezpečí ukončenie stránky a jej odoslanie klientovi. V tomto okamihu som pridal volanie statickej metódy sleep() (môžete použiť aj iný spôsob), ktorá zabezpečí určité (3 sek.) oneskorenie, kým bude poslaná ďalšia stránka. Cyklus sa zopakuje trikrát. Na záver je poslaný obrázok a nastáva zmena content type, čo však zatiaľ prehliadače ignorujú.

Výsledok dnešného príkladu - skutočný
Toto je skutočný výsledok nášho príkladu.

Výsledok dnešného príkladu - očakávaný
A takto by to malo vyzerať v ideálnom prípade.

Starší komentáře ke článku

Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.

Žádný příspěvek v diskuzi

Odpovědět