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.
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. –
@RemyLebeau grazie per i suggerimenti, ho aggiornato il codice – mjn