【问题标题】:How can I update HTML pages dynamically with Indy HTTP server using jQuery and "Long Polling"?如何使用 jQuery 和“Long Polling”通过 Indy HTTP 服务器动态更新 HTML 页面?
【发布时间】:2012-12-26 21:07:10
【问题描述】:

我已阅读文章Simple Long Polling Example with JavaScript and jQuery。 “长轮询 - 一种高效的服务器推送技术”段落解释了这一点

长轮询技术结合了最佳情况的传统轮询 具有持久的远程服务器连接。长期轮询 本身就是长期持有的 HTTP 请求的缩写。

如何实现一个使用长轮询的基于 Indy 的 HTTP 服务器?

【问题讨论】:

    标签: jquery ajax delphi indy long-polling


    【解决方案1】:

    这是一个独立的示例项目,使用 Indy 版本 10.5.9 和 Delphi 2009 进行了测试。

    当应用程序运行时,导航到http://127.0.0.1:8080/。然后服务器将提供一个 HTML 文档(在 OnCommandGet 处理程序中硬编码)。

    此文档包含一个 div 元素,该元素将用作新数据的容器:

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

    JavaScript 代码然后循环向资源/getdata 发送请求(函数poll())。

    服务器响应一个 HTML 片段,其中包含一个带有当前服务器时间的新 &lt;div&gt; 元素。然后,JavaScript 代码将旧的 &lt;div&gt; 元素替换为新元素。

    为了模拟服务器工作,该方法在返回数据之前等待一秒钟。

    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.
    

    【讨论】:

    • 不要让TMyServer 将处理程序分配给它自己继承的OnCommandGet 事件,而是让它覆盖虚拟TIdCustomHTTPServer.DoCommandGet() 方法。另外,在设置Response.ContentType 之后而不是之前设置Response.CharSet。 ContentType 属性设置器可能(并且将来可能会)根据分配的值更改 CharSet,从而失去手动分配。
    猜你喜欢
    • 2018-10-23
    • 1970-01-01
    • 1970-01-01
    • 2011-08-17
    • 2015-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-20
    相关资源
    最近更新 更多