Dưới đây là một dự án ví dụ khép kín, thử nghiệm với Indy phiên bản 10.5.9 và Delphi 2009.
Khi ứng dụng chạy, điều hướng đến http://127.0.0.1:8080/
. Sau đó, máy chủ sẽ phục vụ một tài liệu HTML (được mã hóa cứng trong trình xử lý OnCommandGet).
Tài liệu này chứa một phần tử div mà sẽ được sử dụng như các container cho dữ liệu mới:
<body>
<div>Server time is: <div class="time"></div></div>'
</body>
Các mã JavaScript sau đó gửi yêu cầu đến nguồn /getdata
trong một vòng lặp (chức năng poll()
).
Máy chủ phản hồi với đoạn HTML chứa phần tử <div>
mới với thời gian máy chủ hiện tại. Sau đó, mã JavaScript sẽ thay thế phần tử <div>
cũ bằng phần tử mới.
Để mô phỏng công việc máy chủ, phương thức chờ một giây trước khi trả lại dữ liệu.
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.
Thay vì phải 'TMyServer' gán một handler để thừa hưởng' sự kiện OnCommandGet' riêng của mình, có nó ghi đè lên các ảo TIdCustomHTTPServer.DoCommandGet() 'phương pháp 'để thay thế. Ngoài ra, đặt 'Response.CharSet' sau khi đặt' Response.ContentType' thay vì trước. Các 'ContentType' tài sản setter có thể (và trong tương lai, có khả năng sẽ) thay đổi' CharSet' dựa trên giá trị được giao, do đó mất phân công của bạn bằng tay. –
@RemyLebeau cảm ơn bạn đã gợi ý, tôi đã cập nhật mã – mjn