使用 Delphi 和 IdHTTPServer 的“服务器发送事件”

问题描述 投票:0回答:1

KeepAlive=True 并将标题设置为

'Content-Type: text/event-stream'
'Cache-Control: no-cache'

可以采用Delphi视频流Http服务器中的示例来实现“服务器发送事件”以将数据推送到浏览器网页吗?

我什至不知道 Indy 是否可行,因为我对这项技术真的很陌生

delphi indy server-sent-events
1个回答
0
投票

是的,可以进行调整。尝试这样的事情:

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
对事件。

© www.soinside.com 2019 - 2024. All rights reserved.