2013-01-12 8 views
5

Ho letto l'articolo Simple Long Polling Example with JavaScript and jQuery. Il paragrafo "Long Polling - Un efficiente Tecnica Server-Push" spiega cheCome posso aggiornare le pagine HTML in modo dinamico con il server Indy HTTP usando jQuery e "Polling lungo"?

la tecnica di polling lungo combina il meglio e minuscole polling tradizionale con connessioni al server remoti persistenti. Il termine Long Polling è breve per la richiesta HTTP a lungo termine.

Come è possibile implementare un server HTTP basato su Indy che utilizza il polling lungo?

risposta

4

Ecco un esempio di progetto autonomo, testata con Indy versione 10.5.9 e Delphi 2009.

Quando viene eseguita l'applicazione, passare alla http://127.0.0.1:8080/. Il server servirà quindi un documento HTML (hardcoded nel gestore OnCommandGet).

Questo documento contiene un elemento div che sarà utilizzato come contenitore per i nuovi dati:

<body> 
    <div>Server time is: <div class="time"></div></div>' 
</body> 

Il codice JavaScript quindi inviare le richieste alla risorsa /getdata in un ciclo (funzione poll()).

Il server risponde con un frammento HTML che contiene un nuovo elemento <div> con l'ora del server corrente. Il codice JavaScript sostituisce quindi il vecchio elemento <div> con il nuovo.

Per simulare il lavoro del server, il metodo attende un secondo prima di restituire i dati.

program IndyLongPollingDemo; 

{$APPTYPE CONSOLE} 

uses 
    IdHTTPServer, IdCustomHTTPServer, IdContext, IdSocketHandle, IdGlobal, 
    SysUtils, Classes; 

type 
    TMyServer = class(TIdHTTPServer) 
    public 
    procedure InitComponent; override; 
    procedure DoCommandGet(AContext: TIdContext; 
     ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo); override; 
    end; 

procedure Demo; 
var 
    Server: TMyServer; 
begin 
    Server := TMyServer.Create(nil); 
    try 
    try 
     Server.Active := True; 
    except 
     on E: Exception do 
     begin 
     WriteLn(E.ClassName + ' ' + E.Message); 
     end; 
    end; 
    WriteLn('Hit any key to terminate.'); 
    ReadLn; 
    finally 
    Server.Free; 
    end; 
end; 

procedure TMyServer.InitComponent; 
var 
    Binding: TIdSocketHandle; 
begin 
    inherited; 

    Bindings.Clear; 
    Binding := Bindings.Add; 
    Binding.IP := '127.0.0.1'; 
    Binding.Port := 8080; 

    KeepAlive := True; 
end; 

procedure TMyServer.DoCommandGet(AContext: TIdContext; 
    ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo); 
begin 
    AResponseInfo.ContentType := 'text/html'; 
    AResponseInfo.CharSet := 'UTF-8'; 

    if ARequestInfo.Document = '/' then 
    begin 
    AResponseInfo.ContentText := 
     '<html>' + #13#10 
     + '<head>' + #13#10 
     + '<title>Long Poll Example</title>' + #13#10 
     + ' <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js" type="text/javascript" charset="utf-8"> ' + 
     #13#10 
     + ' </script> ' + #13#10 
     + ' <script type="text/javascript" charset="utf-8"> ' + #13#10 
     + ' $(document).ready(function(){ ' + #13#10 
     + ' (function poll(){' + #13#10 
     + ' $.ajax({ url: "getdata", success: function(data){' + #13#10 
     + '  $("div.time").replaceWith(data);' + #13#10 
     + ' }, dataType: "html", complete: poll, timeout: 30000 });' + #13#10 
     + ' })();' + #13#10 
     + ' });' + #13#10 
     + ' </script>' + #13#10 
     + '</head>' + #13#10 
     + '<body> ' + #13#10 
     + ' <div>Server time is: <div class="time"></div></div>' + #13#10 
     + '</body>' + #13#10 
     + '</html>' + #13#10; 
    end 
    else 
    begin 
    Sleep(1000); 
    AResponseInfo.ContentText := '<div class="time">'+DateTimeToStr(Now)+'</div>'; 
    end; 
end; 

begin 
    Demo; 
end. 
+1

Invece di avere 'TMyServer' assegnare al gestore propria ereditato' evento OnCommandGet', falla sostituire invece il metodo virtuale 'TIdCustomHTTPServer.DoCommandGet()'. Inoltre, imposta 'Response.CharSet' dopo aver impostato' Response.ContentType' piuttosto che prima. Il setter di proprietà 'ContentType' potrebbe (e in futuro, probabilmente lo farà) cambiare il' CharSet' in base al valore assegnato, perdendo così il tuo compito manuale. –

+0

@RemyLebeau grazie per i suggerimenti, ho aggiornato il codice – mjn