How to: update HTML pages dynamically using jQuery and “Long Polling”

Here is a self-contained example project, tested with Indy version 10.5.9 and Delphi 2009.

When the application runs, navigate to http://127.0.0.1:8080/. The server will then serve a HTML document (hard-coded in the OnCommandGet handler).

This document contains a div element which will be used as the container for new data:

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

The JavaScript code then send requests to the resource /getdata in a loop (function poll()).

The server responds with a HTML fragment which contains a new <div> element with the current server time. The JavaScript code then replaces the old <div> element with the new.

To simulate server work, the method waits for one second before returning the data.

    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.
Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s