还不会主动向前端通过SSE推送消息? 看这篇就会了![Delphi版]
zhezhongyun 2025-01-13 19:13 37 浏览
SSE(Server-Send Events)
SSE 是一种在基于浏览器的 Web 应用程序中仅从服务器向客户端发送文本消息的技术。SSE基于 HTTP 协议中的持久连接, 具有由 W3C 标准化的网络协议和 EventSource 客户端接口,作为 HTML5 标准套件的一部分。
使用其他方法实现的很多,采用Delphi实现的却基本没有,请教了一位高手,在他的帮助下实现了,特写下来,希望能帮助到更多的delphier.
废话不多说,直接上代码!
pas如下
unit Unit1;
interface
uses
Winapi.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;
type
TForm1 = 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);
private
procedure SendSSEMessage(const AMessage: string);
public
end;
var
Form1: TForm1;
gConnection : TIdTCPConnection;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
SendSSEMessage(Edit1.Text);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
IdHTTPServer1.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);
var
LFilename: string;
LPathname: string;
begin
LFilename := ARequestInfo.Document;
LPathname := 'E:\Study\SSE' + LFilename;
if FileExists(LPathname) then begin
AResponseInfo.ContentStream := TFileStream.Create(LPathname, fmOpenRead + fmShareDenyWrite);
end else begin
if ARequestInfo.URI = '/subscribe' then begin
with AContext.Connection.IOHandler do begin
WriteBufferOpen;
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);
begin
with gConnection.IOHandler do begin
WriteBufferOpen;
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: TForm1
Left = 0
Top = 0
Caption = 'Form1'
ClientHeight = 242
ClientWidth = 601
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
OnCreate = FormCreate
PixelsPerInch = 96
TextHeight = 13
object Memo1: TMemo
Left = 250
Top = 0
Width = 351
Height = 242
Align = alRight
Lines.Strings = (
'Memo1')
TabOrder = 0
ExplicitLeft = 512
end
object Button1: TButton
Left = 48
Top = 168
Width = 75
Height = 25
Caption = 'Button1'
TabOrder = 1
OnClick = Button1Click
end
object Edit1: TEdit
Left = 48
Top = 32
Width = 121
Height = 21
TabOrder = 2
Text = 'Edit1'
end
object IdHTTPServer1: TIdHTTPServer
Bindings = <>
TerminateWaitTime = 50000
KeepAlive = True
SessionTimeOut = 50000
OnCommandGet = IdHTTPServer1CommandGet
Left = 120
Top = 80
end
end
对应的HTML如下:
<!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中的字符串。
相关推荐
- 字体缩放(方式一)(字体缩放150%怎么做)
-
通过元素宽度和字数计算得到缩放简单实现如下:/***字体最大为视觉要求大小(maxFontSize);超出缩小字体显示,最小为minFontSize;最小字体时超出部分使用圆点(...);*p...
- 网页世界隐藏的神秘代码语言,竟能这样改变布局
-
CSS基础:选择器与属性CSS(CascadingStyleSheets)是用于控制网页外观的一门样式表语言。它通过定义HTML元素的显示方式来增强网页的表现力。CSS的选择器允许开发者精确地定位...
- CSS属性值计算过程详解(css属性用来定义元素计算)
-
在CSS中,即使某些属性没有显式声明,浏览器也会通过**属性值计算过程**为每个元素的所有属性赋予最终值。这一过程分为四个关键步骤,以下将逐一解析。1.确定声明值浏览器首先检查所有**直接应用**到...
- 软网推荐:找回调整Windows 10字号功能
-
之前的系统,从WindowsXP到早期版本的Windows10,均有字体大小调整功能,但从创意者版Windows10以来,取消了之前的设置选项,取而代之的是自定义缩放比例设置。使用这个功能调整过...
- Excel中如何设置文本框属性,实例代码讲解
-
Excel不仅可以对数据进行处理,而且也可以图形化数据,直观显示数据表达的内容。本节介绍一个很重要的对象,Characters,字符对象,使用Characters对象可修改包含在全文本字符串中的任...
- CSS 字体样式(css中字体)
-
本节我们来讲字体样式,之前我们学习HTML的时候学过一些用于字体加粗、倾斜的标签,但是使用标签来实现的效果肯定没有我们通过CSS中的样式来的方便。接下来我们会给大家介绍下面这几个属性的使用:通...
- PC网站建设必备代码知识:HTML基础与应用技巧
-
在PC网站建设的相关课程里,代码扮演着至关重要的角色。只有熟练运用正确的代码,我们才能打造出功能完善、用户体验出色的PC网站。接下来,我会详细讲解在PC网站建设环节中必须了解的代码知识。HTML基础代...
- 让你大跌眼镜的疯狂 HTML 和 CSS 技巧
-
今天,分享一个让你大开眼界的技巧。通过使用这个技巧,你可以将整个网页变成一个CSS编辑器。没错,你从未见过这种方法。当我第一次尝试时,我完全被震惊到了。现在,让我们开始吧!步骤1首先,创建一个基础的...
- jQuery EasyUI使用教程:创建一个链接按钮
-
jQueryEasyUI最新版下载>本教程主要为大家展示如何使用jQueryEasyUI创建一个链接按钮。通常情况下,使用“button/”元素来创建一个按钮;使用“a/”元素来创建链接按钮...
- React 19 有哪些新特性?(react100)
-
如果你对React18还不熟悉,欢迎阅读之前的文章《React18全览[1]》最近React发布了V19RC版本,按照惯例,我们对React19的新特性进行一次深度的体验学习...
- Java注解探秘:为什么@PostConstruct能解决你的初始化难题?
-
你是否在Spring项目中遇到过这样的困扰:明明依赖注入已经完成,但某些配置就是无法正常加载?手动调用初始化方法又容易引发空指针异常?这就是@PostConstruct注解大显身手的时候了!@Post...
- AI驱动的表单自动填写(ai置入表格)
-
我们都同意,填写表格是一项枯燥且耗时的任务。如果我们可以创建一个可以为我们填写表格的AI助手,让我们将时间投入到更有建设性的任务中,那会怎样?AI助手将能够通过调用以表单字段为参数的函数来填写表...
- 从零到一:小程序设计新手如何快速上手?
-
开发环境搭建对于小程序设计新手而言,搭建合适的开发环境是首要任务。以小程序为例,其官方提供了功能强大的开发工具——开发者工具。首先,新手需前往官方开发者平台,在页面中找到“工具下载”板块,根据...
- JavaSwingGUI从小白到大神-6(续)(java从小白到大牛怎么样)
-
接上一篇《JavaSwingGUI从小白到大神-6》,因本篇文章3万多字,头条一篇发不完,只能分开发。同事查询面板:CompanyFind.javapublicclassCompanyFind{...
- C# winform界面假死(c#程序假死)
-
针对C#WinForm界面假死问题,以下是分步解决方案:1.使用异步编程(async/await)将耗时操作移至后台线程,保持UI线程响应。步骤:将事件处理函数标记为async。使用Task....
- 一周热门
- 最近发表
- 标签列表
-
- HTML 教程 (33)
- HTML 简介 (35)
- HTML 实例/测验 (32)
- HTML 测验 (32)
- HTML 参考手册 (28)
- JavaScript 和 HTML DOM 参考手册 (32)
- HTML 拓展阅读 (30)
- HTML中如何键入空格 (27)
- HTML常用标签 (29)
- HTML文本框样式 (31)
- HTML滚动条样式 (34)
- HTML5 浏览器支持 (33)
- HTML5 新元素 (33)
- HTML5 WebSocket (30)
- HTML5 代码规范 (32)
- HTML5 标签 (717)
- HTML5 标签 (已废弃) (75)
- HTML5电子书 (32)
- HTML5开发工具 (34)
- HTML5小游戏源码 (34)
- HTML5模板下载 (30)
- HTTP 状态消息 (33)
- HTTP 方法:GET 对比 POST (33)
- 键盘快捷键 (35)
- 标签 (226)