KeepAlive=True 并将标题设置为
'Content-Type: text/event-stream'
'Cache-Control: no-cache'
可以采用Delphi视频流Http服务器中的示例来实现“服务器发送事件”以将数据推送到浏览器网页吗?
我什至不知道 Indy 是否可行,因为我对这项技术真的很陌生
是的,可以进行调整。尝试这样的事情:
type
TMyContext = class(TIdServerContext)
Events: TIdThreadSafeObjectList;
Signal: TEvent;
constructor Create(AConnection: TIdTCPConnection; AYarn: TIdYarn; AList: TIdContextThreadList = nil); override;
destructor Destroy;
procedure AddEvent(AStrings: TStrings);
end;
constructor TMyContext.Create(AConnection: TIdTCPConnection; AYarn: TIdYarn; AList: TIdContextThreadList = nil);
begin
inherited Create(AConnection, AYarn, AList);
Events := TIdThreadSafeObjectList.Create;
Events.OwnsObjects := True;
Signal := TEvent.Create;
end;
destructor TMyContext.Destroy;
begin
Events.Free;
Signal.Free;
inherited;
end;
procedure TMyContext.AddEvent(AStrings: TStrings);
var
Event: TStringList;
List: TList;
begin
Event := TStringList.Create;
try
Event.Assign(AStrings);
List := Events.LockList;
try
List.Add(Event);
Signal.SetEvent;
finally
Events.UnlockList;
end;
except
Event.Free;
raise;
end;
end;
procedure TForm1.Form1Create(Sender: TObject);
begin
IdHTTPServer1.ContextClass := TMyContext;
...
end;
procedure TForm1.IdHTTPServer1CommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var
List: TList;
Event: TStringList;
I, J: Integer;
begin
if ARequestInfo.Document <> '/' then
begin
AResponseInfo.ResponseNo := 404;
Exit;
end;
AResponseInfo.ResponseNo := 200;
AResponseInfo.ContentType := 'text/event-stream';
AResponseInfo.CloseConnection := False;
AResponseInfo.WriteHeader;
AContext.Connection.IOHandler.DefStringEncoding := IndyTextEncoding_UTF8;
repeat
case TMyContext(AContext).WaitFor(10000) of
wrTimeOut:
begin
AContext.Connection.IOHandler.WriteLn(':');
AContext.Connection.IOHandler.WriteLn;
end;
wrSignaled:
begin
List := TMyContext(AContext).Events.LockList;
try
while List.Count > 0 do
begin
Event := TStringList(List[0]);
List[I].Delete(0);
try
for J := 0 to Event.Count-1 do
AContext.Connection.IOHandler.WriteLn(Event.Names[I] + ': ' + Eveent.ValueFromIndex[I]);
AContext.Connection.IOHandler.WriteLn;
finally
Event.Free;
end;
end;
TMyContext(AContext).Signal.ResetEvent;
finally
TMyContext(AContext).Events.UnlockList;
end;
end;
end;
until False;
end;
然后,您只需在需要时在任何连接上调用
TMyContext.AddEvent()
即可向其发送 name=value
对事件。