还不会主动向前端通过SSE推送消息? 看这篇就会了![Delphi版]

SSE(Server-Send Events)SSE 是一种在基于浏览器的 Web 应用程序中仅从服务器向客户端发送文本消息的技术 。SSE基于 HTTP 协议中的持久连接,具有由 W3C 标准化的网络协议和 EventSource 客户端接口,作为 html5 标准套件的一部分 。
使用其他方法实现的很多,采用Delphi实现的却基本没有,请教了一位高手,在他的帮助下实现了,特写下来,希望能帮助到更多的delphier.
废话不多说,直接上代码!
pas如下
unit Unit1;interfaceusesWinapi.windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,Vcl.Controls, Vcl.Forms, Vcl.Dialogs, IdContext, IdCustomHTTPServer, IdHTTPServer,IdTCPConnection,IdBaseComponent, IdComponent, IdCustomTCPServer, Vcl.StdCtrls;typeTForm1 = class(TForm)IdHTTPServer1: TIdHTTPServer;Memo1: TMemo;Button1: TButton;Edit1: TEdit;procedure FormCreate(Sender: TObject);procedure IdHTTPServer1CommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo;AResponseInfo: TIdHTTPResponseInfo);procedure Button1Click(Sender: TObject);privateprocedure SendSSEMessage(const AMessage: string);publicend;varForm1: TForm1;gConnection : TIdTCPConnection;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);beginSendSSEMessage(Edit1.Text);end;procedure TForm1.FormCreate(Sender: TObject);beginIdHTTPServer1.DefaultPort := 80; // 设置服务器端口IdHTTPServer1.ServerSoftware := 'Delphi SSE Server'; // 设置服务器名称IdHTTPServer1.Active := True;idHttpServer1.Active:= True;Memo1.Lines.Add('Server started...');end;procedure TForm1.IdHTTPServer1CommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo;AResponseInfo: TIdHTTPResponseInfo);varLFilename: string;LPathname: string;beginLFilename := ARequestInfo.Document;LPathname := 'E:StudySSE' + LFilename;if FileExists(LPathname) then beginAResponseInfo.ContentStream := TFileStream.Create(LPathname, fmOpenRead + fmShareDenyWrite);end else beginif ARequestInfo.URI = '/subscribe' then beginwith AContext.Connection.IOHandler do beginWriteBufferOpen;WriteLn('HTTP/1.1 200 OK');WriteLn('Content-Type: text/event-stream; charset=UTF-8');WriteLn('Cache-Control: no-cache');WriteLn('Connection: keep-alive');WriteLn();WriteBufferClose;end;//gConnection:= AContext.Connection;end;end;end;procedure TForm1.SendSSEMessage(const AMessage: string);beginwith gConnection.IOHandler do beginWriteBufferOpen;WriteLn('id:'+IntToStr(random(1000))+#13#10);WriteLn('event:test'+#13#10);WriteLn('data:'+AMessage+#13#10#13#10);WriteBufferClose;end;end;end.dfm如下:
object Form1: TForm1Left = 0Top = 0Caption = 'Form1'ClientHeight = 242ClientWidth = 601Color = clBtnFaceFont.Charset = DEFAULT_CHARSETFont.Color = clWindowTextFont.Height = -11Font.Name = 'Tahoma'Font.Style = []OldCreateOrder = FalseOnCreate = FormCreatePixelsPerInch = 96TextHeight = 13object Memo1: TMemoLeft = 250Top = 0Width = 351Height = 242Align = alRightLines.Strings = ('Memo1')TabOrder = 0ExplicitLeft = 512endobject Button1: TButtonLeft = 48Top = 168Width = 75Height = 25Caption = 'Button1'TabOrder = 1OnClick = Button1Clickendobject Edit1: TEditLeft = 48Top = 32Width = 121Height = 21TabOrder = 2Text = 'Edit1'endobject IdHTTPServer1: TIdHTTPServerBindings = <>TerminateWAItTime = 50000KeepAlive = TrueSessionTimeOut = 50000OnCommandGet = IdHTTPServer1CommandGetLeft = 120Top = 80endend对应的HTML如下:
【还不会主动向前端通过SSE推送消息? 看这篇就会了![Delphi版]】<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title><script>window.onload = ()=> {console.log("onload!");if (window.EventSource) {let source = new EventSource("/subscribe");let s = '';//source.addEventListener('message', function(e) {console.log("connect message");document.querySelector("p").innerText = e.data;})source.addEventListener('open',function(e){console.log("connect is open");},false);source.addEventListener('error',function(e){if(e.readyState == EventSource.CLOSE){console.log("connect is close");console.log('connection state: ' + source.readyState + ', error: ' + event);console.log(event);}else{console.log(e.readyState);}},false);} else {alert("浏览器不支持EventSource");}}</script></head><body><p></p></body></html>编译版是Delphi 10.4.2
点击Button1,即可向前端推送Edit1中的字符串 。

还不会主动向前端通过SSE推送消息? 看这篇就会了![Delphi版]

文章插图
 




    推荐阅读