导航:
论坛 -> Web应用开发
斑竹:bodies
作者:
2018/5/20 18:30:46
标题:
使用http.sys,让delphi的多层服务真的飞起来
浏览:29903
加入我的收藏
楼主:
原delphi窑洞洞主xalion在自己的博客上发过一篇文章: 《使用http.sys,让delphi 的多层服务飞起来》 http://www.cnblogs.com/xalion/p/6219515.html 这里边提到如何把mormot的httpserver抠出来,嫁接到webbroker上,非常好的思路。 可惜xalion没贴出全部源代码。 最近对WebBroker做了点深入研究,给出了c5soft的实现,贴出全部源代码。 目前是0.0.0.1版本,仅搭了个框架,但是明眼人一看就明白实现思路,一步一步可以把整个框架填满。 源代码在Delphi7 与Delphi 10.2下编译通过。
----------------------------------------------
-
作者:
2018/5/20 18:31:23
1楼:
执行截图
此帖子包含附件: 大小: 81.1K
----------------------------------------------
-
作者:
2018/5/20 19:14:28
2楼:
学习学习,谢谢星5
----------------------------------------------
-
作者:
2018/5/20 19:16:33
3楼:
可行吗?
----------------------------------------------
-
作者:
star5 (星五)
★☆☆☆☆
-
盒子活跃会员
2018/5/20 19:23:08
4楼:
2楼,是C5,不是星5 下载看看
----------------------------------------------
博客 - http://offeu.com 脚本模型 - http://webpascal.com 需要短信接口的请联系我,可发行业与营销内容。
作者:
2018/5/20 19:29:42
5楼:
支持D7就是好!
----------------------------------------------
声明:本人不在论坛询问任何编程问题,请不要将我的帖子当成问题来回答。炒股一天,编程三年,不浪费时间了。 经常在外面,没空,不要找我..
作者:
2018/5/20 19:39:01
6楼:
框架使用方法: 第一步,新建WebServer Application
此帖子包含附件: 大小: 79.6K
----------------------------------------------
-
作者:
2018/5/20 19:40:28
7楼:
第二步,选择 CGI Standalone Executable
此帖子包含附件: 大小: 47.0K
----------------------------------------------
-
作者:
2018/5/20 19:43:34
8楼:
第三步,将c5soft写的SynWebApp.pas放到项目文件夹下,修改dpr文件, 将CGIApp替换为SynWebApp in 'SynWebApp.pas'
此帖子包含附件: 大小: 80.2K
----------------------------------------------
-
作者:
2018/5/20 19:44:51
9楼:
后续要点:要让程序编译通过,需要下载mORMot的源文件,并将mORMot添加到Delphi的库搜寻路径中。剩下的要是还不会,就去看web broker开发文档了。
此帖子包含附件: 大小: 108.5K
----------------------------------------------
-
作者:
2018/5/20 20:56:35
10楼:
c5soft大侠一直是个热心人。感谢!
----------------------------------------------
-
作者:
2018/5/20 21:08:08
11楼:
这么多人喜欢这个http.sys么。 不如去折腾libuv. 跨平台的库,好像有一个delphi的翻译版
----------------------------------------------
--
作者:
2018/5/20 21:37:24
12楼:
libuv的是nodejs的底层,异步,事件驱动,用Nodejs就是在用libuv。在Nodejs上目前最棒的框架是KOA。寸有所长,尺有所短。Nodejs强大,仍有不少场合不适合用javascript来写。Web开发可以将nodejs与Delphi结合起来用,各取所长。
----------------------------------------------
-
作者:
2018/5/20 21:58:22
13楼:
没让去用node.js,我是说直接引用libuv库,可以编译成obj直接在delphi里使用。
----------------------------------------------
--
作者:
2018/5/20 22:59:45
14楼:
通过编译到exe中使用与通过http协议相互调用,能达到同样的效果。在Nodejs里可以通过Node-fetch调用mORMot,在mORMot里可以通过THttpClientSocket调用Nodejs。要讲效率当然是前者,后者的优势是成熟。
----------------------------------------------
-
作者:
2018/5/20 23:04:05
15楼:
希望彻底搞懂WebBroker的朋友可以看看flier (小海 //爱喝可乐^_^)写的刨析文稿。我收录在这里:http://www.cnblogs.com/c5soft/p/webbroker.html
----------------------------------------------
-
作者:
2018/5/20 23:33:28
16楼:
datasnap rest的技术也是基于webbroker的。
----------------------------------------------
-
作者:
2018/5/20 23:52:44
16楼:
好贴!
----------------------------------------------
学无止境
作者:
2018/5/21 9:02:50
17楼:
顶,好东西
----------------------------------------------
他们总是取笑失败者,以酷似智者;他们也总是为成功者喝采,以取得赏金。
作者:
2018/5/21 9:14:42
18楼:
顶一下,好东西
----------------------------------------------
XE7 安卓手机框架、IOS手机框架开发,联系QQ:2403182533
作者:
2018/5/22 8:27:51
19楼:
感谢大神的分享精神
----------------------------------------------
-
作者:
2018/5/22 8:52:47
20楼:
最近一直在搞webbroker,正好参考下 多谢
----------------------------------------------
-
作者:
2018/5/22 10:23:30
21楼:
这个是cgi的,独立exe 需要替换IdHTTPWebBrokerBridge,还要自己实现 xalion上有定义, 没代码
----------------------------------------------
-
作者:
2018/5/22 11:26:53
22楼:
@olddelphier:不要搞错,不是cgi了,是Bridge,但是我这个实现比xalion那个要简单易懂。无需开启iis,对delphi编译的exe一启动,通过浏览器就能接入。
----------------------------------------------
-
作者:
2018/5/22 12:04:25
23楼:
启动时出现错误: First chance exception at $73CED722. Exception class EHttpApiServer with message 'HttpSetServiceConfiguration failed: 拒绝访问。 (5)'. Process SynBrokerTest.exe (198108) 是哪里需要设置?
----------------------------------------------
-
作者:
2018/5/22 12:12:17
24楼:
mORMot 请下载1.18版,nightly
----------------------------------------------
-
作者:
2018/5/22 12:43:34
25楼:
xe4下了最新的mormot 把几个string改成ansistring 直接就可以跑了
----------------------------------------------
-
作者:
2018/5/22 13:03:21
26楼:
改string为ansiStrin后D10.2.3就编译不了,最好改成条件编译。
----------------------------------------------
-
作者:
2018/5/22 14:15:46
27楼:
试了下,可以在原来的项目中直接引用 SynWebApp替换IdHTTPWebBrokerBridge就可以过渡 多谢
----------------------------------------------
-
作者:
2018/5/22 14:30:06
28楼:
TWebRequest部分仅实现了GET的部分转换,queryFields还未做,POST的转换还未做ContentFields未做; TWebResponse部分仅写了Content与ContentType,ConentStream尚未做。 再深度一点,WebModule里面需要实现静态文件服务与Session管理(这两个功能也可以直接放在Process里面),才能把网站架起来。 各位大侠,抽空把这些空缺补上。 随便吐槽:c5soft这么好的方案,怎么就没有掌声呢?难道就真没有几个人懂WebBroker吗?
----------------------------------------------
-
作者:
2018/5/22 14:41:37
29楼:
那些可以参考以前的indy webrequest和webresponse 来完善
----------------------------------------------
-
作者:
2018/5/22 15:24:59
30楼:
我是从synopse.info网站上的下载链接下载的:https://github.com/synopse/mORMot/archive/master.zip 在Win10 X64环境下,必须以管理员身份启动Delphi,才能不出现“拒绝访问”错误。
此帖子包含附件: 大小: 89.8K
----------------------------------------------
-
作者:
2018/5/22 15:29:10
31楼:
奇怪,现在不用管理员身份也可以了。
----------------------------------------------
-
作者:
2018/5/22 15:41:55
32楼:
@vclclx 程序中AddUrl与RemoveURL调用是需要管理员权限,编译后的exe需要以管理员身份运行,或者直接以管理员身份运行delphi编译调式。 或者将dpr改一下,包含mORMot包中的vistaAdm.RES,强制程序以管理员身份运行: program SynBrokerTest; {$APPTYPE CONSOLE} uses {$R vistaAdm.RES} {$IFNDEF UNICODE} FastMM4, {$ENDIF} WebBroker, SynWebApp in 'SynWebApp.pas', uWebModule in 'uWebModule.pas' {WebModule1: TWebModule}; {$R *.res} begin {$IFDEF UNICDOE} ReportMemoryLeaksOnShutDown := True; {$ENDIF} Application.Initialize; Application.CreateForm(TWebModule1, WebModule1); Application.Run; end.
----------------------------------------------
-
作者:
2018/5/22 16:07:28
33楼:
虽然我直接就用mORMot,但是仍然支持楼主!
----------------------------------------------
-
作者:
2018/5/22 16:47:00
34楼:
@edwinyeah 我也直接用mORMot写了个WebServer,正7x24小时在业务中跑。Session管理,静态文件下载服务,文件上传服务都跑得很好。数据库我直接用ADOInt中的_Recordset,不用TDataset,直接用微软的东西,Bug更少。Delphi7编译后exe文件大小是855KM,AsPack压缩后326KB。 现在问题来了,客户希望在WebServer中提供SOAP WebService服务,本想自己写一个SOAP接口挂在mORMot上,想了想工作量太大。Delphi里SOAP是现成的,但是走的是WebBroker这条路,这才反过来用mORMot做WebBroker的底层。
此帖子包含附件: 大小: 185.8K
----------------------------------------------
-
作者:
2018/5/22 17:06:20
35楼:
好东西。顶c5soft大虾!
----------------------------------------------
喜欢Delphi,关注Delphi,愿和广大爱好者交朋友。
作者:
2018/5/22 17:19:31
36楼:
WebBroker设计得稍微复杂,让初学者丈二和尚摸不到头脑,其实就是解决一个路由问题,将URL定位到一段处理程序。用一个数组,两个函数就搞定了。 这是c5soft的非webBroker实现: type TDispatchAction = function(const Env: TWebEnv): Boolean; TRouteMap = record MethodAndPathInfo: RawUTF8; Action: TDispatchAction; end; var RouteMapList: array of TRouteMap; procedure RouteMap(const Method, PathInfo: RawUTF8; const Action: TDispatchAction); var nLen: Integer; begin nLen := Length(RouteMapList); Inc(nLen); SetLength(RouteMapList, nLen); Dec(nLen); RouteMapList[nLen].MethodAndPathInfo := UpperCase(Method + ':' + PathInfo); RouteMapList[nLen].Action := Action; end; function RouteDispatch(const AEnv: TWebEnv; AMethodAndPathInfo: RawUTF8 = ''): Boolean; var i: Integer; rm: TRouteMap; cScheme: RawUTF8; bFound: Boolean; begin Result := False; if AMethodAndPathInfo = '' then AMethodAndPathInfo := PUTF8Char(AEnv.MethodAndPathInfo); for i := Length(RouteMapList) - 1 downto 0 do begin rm := RouteMapList[i]; if AEnv.SSL then cScheme := 'HTTPS ' else cScheme := 'HTTP '; bFound := IdemPChar(PUTF8Char(cScheme + AMethodAndPathInfo), PAnsiChar(rm.MethodAndPathInfo)); if not bFound then begin bFound := IdemPChar(PUTF8Char(AMethodAndPathInfo), PAnsiChar(rm.MethodAndPathInfo)); end; if bFound then begin Result := rm.Action(AEnv); break; end; end; end;
----------------------------------------------
-
作者:
2018/5/22 17:38:57
37楼:
RouteDispatch函数在Server的Process中调用,实现路由委派, RouteMap在各个功能模块的initialization里调用,往RouteMapList里注册本模块。 这是Sever的Process: function TWebServer.Process(AContext: THttpServerRequest): cardinal; var ... begin try ... Session := Session.Create(Self, AContext); try ... if RouteDispatch(Session) then begin ... Result := 200 end else begin ... Static File end; end; end; finally FreeAndNil(Session); ... end; except on E: Exception do begin ... Result := 500; end; end end; 下面是功能模块的写法: unit uMapPHLogin; interface implementation uses SysUtils, SynCommons, TypInfo, Classes, uWebDatabase, uWebServer, uWebSessionPH, uWebUtils; function RouteMapLogin(const Env: TWebEnv): Boolean; var Session: TWebSessionPayHelper absolute Env; ... jo: PDocVariantData; jv: Variant begin jo := DocVarInit(jv); ... Session.OutJSon(jo); Result := True; end; function RouteMapChangePwd(const Env: TWebEnv): Boolean; var ... begin ... Session.OutJSon(jo); Result := True; end; function RouteMapChangePwdPost(const Env: TWebEnv): Boolean; var ... jo: PDocVariantData; jv: Variant; begin jo := DocVarInit(jv); ... Session.OutJSon(jo); Result := True; end; ... initialization RouteMap('HTTPS GET', '/rest/login', RouteMapLogin); RouteMap('HTTPS GET', '/rest/refreshOnLine', RouteMapRefreshOnLine); RouteMap('HTTPS GET', '/rest/TChangePwd', RouteMapChangePwd); RouteMap('HTTPS POST', '/rest/TChangePwd', RouteMapChangePwdPost); RouteMap('HTTPS GET', '/rest/TAbout', RouteMapAbout); RouteMap('HTTPS GET', '/rest/TBye.html', RouteMapBye); end.
----------------------------------------------
-
作者:
2018/5/22 19:37:26
38楼:
SynBroker 0.0.0.2 版 增加WBString类型及与RawUTF8的转换 让程序在Delphi 7/XE/10.2.3下能够同时编译,项目文件: Delphi 7: synBrokerTest Delphi XE: synBrokerTestD15 Delphi 10.2.3: synBrokerTestD25,支持Win64 //CompilerVersion<Delphi2009 or CompilerVersion>Delphi 10 Seattle type {$IF (CompilerVersion<20.0) OR (CompilerVersion>=30.0) } WBString = string; {$ELSE} WBString = AnsiString; {$IFEND} function UTF8ToWBString(const AVal: RawUTF8): WBString; function WBStringToUTF8(const AVal: WBString): RawUTF8;
----------------------------------------------
-
作者:
2018/5/22 20:01:04
39楼:
恕我愚钝,大神可否让delphi 10.2.3中的datasnap用上http.sys呢?我真正不会干这个活,把morMot中的httpserver抠出来,嫁接到datasnap上。我想这样,让datasnap 弃用indy,让http.sys做底层,一定会让datasnap性能提高很多。
----------------------------------------------
-
作者:
2018/5/22 20:08:01
39楼:
为c5soft点赞!学习中....
----------------------------------------------
-
作者:
2018/5/22 21:25:09
40楼:
@sxqwhxq 将DataSnap的底层换成mORMot的http.sys关键步骤,以D10.2.3为例: 第一步:选WebBroker服务器类型
此帖子包含附件: 大小: 73.9K
----------------------------------------------
-
作者:
2018/5/22 21:26:59
41楼:
第二步:选Console App类型
此帖子包含附件: 大小: 56.5K
----------------------------------------------
-
作者:
2018/5/22 21:29:01
42楼:
第三步:选择Http通讯协议
此帖子包含附件: 大小: 94.4K
----------------------------------------------
-
作者:
2018/5/22 21:35:12
43楼:
第四步:修改dpr文件,uses里面用SynWebApp替换IdHTTPWebBrokerBridge,后续执行代码全部清除,写成下面这个样子,应该就能编译了。 program Project2; {$APPTYPE CONSOLE} uses System.SysUtils, System.Types, IPPeerServer, IPPeerAPI, //IdHTTPWebBrokerBridge, SynWebApp, Web.WebReq, Web.WebBroker, Datasnap.DSSession, ServerMethodsUnit1 in 'ServerMethodsUnit1.pas', WebModuleUnit1 in 'WebModuleUnit1.pas' {WebModule1: TWebModule}, ServerConst1 in 'ServerConst1.pas'; {$R *.res} begin {$IFDEF UNICDOE} ReportMemoryLeaksOnShutDown := True; {$ENDIF} Application.Initialize; Application.WebModuleClass:=WebModuleClass; Application.Run; end. 其中的关键是: Application.WebModuleClass:=WebModuleClass; 当然,要让程序跑起来,需要全功能的SynWebApp.pas,目前这个模块还没写完。
----------------------------------------------
-
作者:
2018/5/22 21:51:49
43楼:
把工程中的所有有IdHTTPWebBrokerBridge单元都换为SynWebApp? 这个怎么办呢? unit FormUnit1; interface uses Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.AppEvnts, Vcl.StdCtrls, IdHTTPWebBrokerBridge, Web.HTTPApp; 还有,这个全局变量: procedure TForm1.FormCreate(Sender: TObject); begin FServer := TIdHTTPWebBrokerBridge.Create(Self);//这个全局变量怎么办? end;
----------------------------------------------
-
作者:
2018/5/22 22:18:41
44楼:
这个技术贴,支持呀,
----------------------------------------------
我是菜鸟,己经搞了十多年了,但是我仍然很菜。
作者:
2018/5/22 22:27:50
45楼:
@sxqwhxq 出现这种情况是建立工程的时候选择了GUI,没选Console,把程序文件备份出来,重建一下工程,引用以前的源代码就可以了。 作为服务器程序,选择GUI是浪费资源。
此帖子包含附件: 大小: 73.9K
----------------------------------------------
-
作者:
2018/5/22 22:36:41
46楼:
是。我再碰碰运气。看能否把datasnap这头老牛重新吃上嫩草。
----------------------------------------------
-
作者:
2018/5/22 22:42:13
47楼:
前面第四步,修改dpr的忘了处理TDSSessionManager了,修改后代码应该是这个样子: program Project2; {$APPTYPE CONSOLE} uses System.SysUtils, System.Types, IPPeerServer, IPPeerAPI, //IdHTTPWebBrokerBridge, SynWebApp, Web.WebReq, Web.WebBroker, Datasnap.DSSession, ServerMethodsUnit1 in 'ServerMethodsUnit1.pas', WebModuleUnit1 in 'WebModuleUnit1.pas' {WebModule1: TWebModule}, ServerConst1 in 'ServerConst1.pas'; {$R *.res} begin {$IFDEF UNICDOE} ReportMemoryLeaksOnShutDown := True; {$ENDIF} Application.Initialize; Application.WebModuleClass:=WebModuleClass; Application.Run; if TDSSessionManager.Instance <> nil then TDSSessionManager.Instance.TerminateAllSessions; end.
----------------------------------------------
-
作者:
2018/5/22 23:14:05
48楼:
还有一个简单办法,就是仿照TIdHTTPWebBrokerBridge写一个TSynHTTPWebBrokerBridge,单元名称就叫SynHTTPWebBrokerBridge.pas,这样一个结构: TSynWebReqest = class(TWebRequest) ... TSynWebResponse = class(TWebResponse) ... TSynWebServer=Class(TComponent) protected fHttpServer:THttpApiServer; function Process(AContext: THttpServerRequest): cardinal; public ... end; implementation var SynWebRequestHandler: TRequestHandler = nil; ... TSynWebServer.Process(AContext: THttpServerRequest): cardinal; var HTTPRequest: TSynWebReqest; HTTPResponse: TSynWebResponse; begin Result := 200; try HTTPRequest := TSynWebReqest.Create(AContext); try HTTPResponse := TSynWebResponse.Create(HTTPRequest); HTTPResponse.StatusCode := 200; try SynWebRequestHandler.HandleRequest(HTTPRequest, HTTPResponse); Result := HTTPResponse.StatusCode; finally HTTPResponse.Free; end; finally HTTPRequest.Free; end; except //HandleServerException(ExceptObject, Output); end; end; end; function createSynWebRequestHandler:TRequestHandler; begin if SynWebRequestHandler=nil then SynWebRequestHandler:=TRequestHandler.create; return SynWebRequestHandler; end; initialization WebReq.WebRequestHandlerProc := createSynWebRequestHandler; finalization FreeAndNil(SynWebRequestHandler); 如此而已。可以将TSynWebReqest /TSynWebResponse实现与前面SynWebApp.pas中的实现合并成一个单元。叫SynReqRes.pas吧。
----------------------------------------------
-
作者:
2018/5/22 23:34:48
49楼:
WebBroker换底层,实现路由的关键在于从mORMot的Process中调用: HandleRequest(HTTPRequest, HTTPResponse); 在synWebApp.pas单元中TSynWebApplication->TWebApplication->TWebRequestHandler, Application是TWebRequestHandler的实例,调用自身的HandleRequest就可以了。 在SynHTTPWebBrokerBridge.pas单元,需要事先初始一个TWebRequestHandler,在Process中调用:SynWebRequestHandler.HandleRequest(HTTPRequest, HTTPResponse);
----------------------------------------------
-
作者:
2018/5/23 7:41:02
50楼:
SynWebApp里面还有很多函数没有完成。另外,您这种技术可用于datasnap rest吗?
----------------------------------------------
-
作者:
2018/5/23 8:14:42
51楼:
应该是可以的,路由解析都是WebBroker这个套路。不过Rest Server直接用mORMot作者a.b.的那一套也是可行的。 我这里给大家捋捋思路,希望起到一个抛砖引玉的作用,欢迎各位贡献源代码,也欢迎大咖们拍砖。
----------------------------------------------
-
作者:
2018/5/23 14:35:21
52楼:
放一个压力测试结果,10000次并发,SQL Server数据库,64位编译。微软的排队机制就是牛,用ab做压力测试的时候还不影响正常业务。
此帖子包含附件: 大小: 332.1K
----------------------------------------------
-
作者:
2018/5/23 14:48:22
53楼:
如果能找 500 个实体 计算机。 每一个计算机 开 2 个线程。 每个线程 死循环 执行 查询 操作 。 应该算是 1000 个并发了吧。 或者 找 1000 个计算机。 每一个计算机开一个线程。 或者 10 个计算机。 每个计算机 10 个CPU 核心。 每一个核心开 一个 线程。 那么 这样做 和 一个 4核心 CPU 的计算机,开 1000 个线程,有什么区别。
----------------------------------------------
(C)(P)Flying Wang
作者:
2018/5/23 14:52:13
54楼:
@c5soft 您好,我按照您的方法已经编译通过了,但是我修改了您的SynWebApp.pas内的端口“8080”为“80”之后访问提示 Internal Application Error Abstract Error 特向您请教一下是什么原因?
----------------------------------------------
-
作者:
2018/5/23 15:50:57
55楼:
@ilikejava: 可能是80端口已经被占用了,试一下别的端口。 @wang_80919:并发,concurrecy,强调的是服务器端同一ip地址同一端口收到的同时访问个数,与客户端无关。压力测试时通过专门的软件多线程同时发出http请求模拟网络环境。比较好的工具是随Apache httpd同时发行的工具ab.exe。 这是apache httpd 2.4.33附带的最新版本 的ab.exe和一个以前收集的使用说明:
----------------------------------------------
-
作者:
2018/5/23 16:09:30
56楼:
你用 1 台 计算机 模拟 1000 台出来的效果和 100 台模拟出来 1000 台的效果,我个人认为是有差别的。
----------------------------------------------
(C)(P)Flying Wang
作者:
2018/5/23 16:32:40
56楼:
看过本站sxqwhxq (步惊云)发的DataSnap压力测试的一个帖子: http://bbs.2ccc.com/topic.asp?topicid=547409 给人的印象是Delphi做Web服务,并发效果很不理想。 其实效果的好坏取决与两个因素:其一:http底层用哪个,其二:32位编译还是64位编译。 我估计sxqwhxq测试中http底层一定是用的indy控件,并且是32位编译。 http底层用哪家决定了处理并发的机制,是普通多线程还是iocp,另外一个就是稳定性即Bug多少。indy成功的案例还是比较少,不如用WinInet。 因为Delphi开发的并发处理本质上还是离不开多线程机制,每个线程占用一定内存资源,32位编译要实现万次并发绝对没戏,用mORMot技术在Delphi7/XE下编译照样没戏,一会儿就out of memory了,最后发布的时候一定要64位编译。 总结:用上mORMot的http.sys引擎,通过64位编译,终于让Delphi摆脱不能做企业网站的坏名声。咱们用Delphi做的东西终于可以与php/timcat/nodejs一争高下,做出7x24永远不宕机的产品。
----------------------------------------------
-
作者:
2018/5/23 18:07:06
57楼:
上面那个压力测试是本机对本机访问,相当于对127.0.0.1测试的结果,仅能说明软件的稳定性。下面这个测试结果是本机对他机测试,其速度才有参考价值。 发出50万条请求,每次并发1万条,从服务器上打开数据库,返回查询结果。花了2.8小时完成了测试。 测试充当服务器机器的机器是一台联想的台式机,64G内存,i7-6700四核处理器,三星960 PRO固态硬盘,Win10企业版。用D10.2.3编译,底层mORMot,上层用的是我自己的Web框架,未用WebBroker。 测试结果看来相当完美,仅有1个Length错误,就是收到内容实际长度与http头中Content-Length的值不一样,这应该是网络坏境的原因。 为了观察压力测试对实际业务的影响,我特意通过防火墙将生产坏境的服务器访问重定向到这台测试机了,结果没有接到任何客户的不良反馈,通过Chrome中的调试工具监控,仅仅响应时间比为开压力测试前变慢了一些,从100ms以下到200-300ms,在客户的可容忍范围。说明http.sys的排队机制相当完美。
此帖子包含附件: 大小: 373.4K
----------------------------------------------
-
作者:
2018/5/23 18:16:02
58楼:
在任天堂的游戏机上到处都是 INDY 的成功案例。否则游戏就别玩了。
----------------------------------------------
(C)(P)Flying Wang
作者:
2018/5/23 18:53:11
59楼:
c5soft大神:您用ab的测试似乎是固定结果的静态网页,能否用带数据库查询的动态网页呢?动态网页用ab测试有很高的错误率,建议用jmter测试。 上次高同学给我一个测试用中间件,好像是结合了kbmMw和morMot的(底层是基于indy还是http.sys也搞不清)的,用jmter测试,性能大约是datasnap rest的50倍,稳定性更是datasnap不能匹敌的,令人佩服的是,在5000个并发,没有一个错误,而datasnap 基本有30%的错误。
----------------------------------------------
-
作者:
2018/5/23 19:37:26
60楼:
我贴出来的测试是访问数据库,根据id返回一个加密的xml,可以看成是一个静态页面,用于测试系统的承接能力与数据库性能。 上面的测试数据库连接池未打开,还是那50万个连接,正在测试打开连接池的结果。 还用AB, 回头我在服务器端写一个专门用于测试用的模块,让访问的表随机,字段数随机,记录数随机,测试一下差错情况。 JM太复杂,懒得摸去。
----------------------------------------------
-
作者:
dunken (dunken)
★☆☆☆☆
-
盒子活跃会员
2018/5/23 21:17:15
61楼:
顶
----------------------------------------------
-
作者:
ritapl (ritapl)
★☆☆☆☆
-
盒子活跃会员
2018/5/24 10:56:46
62楼:
@c5soft 还有一个简单办法,就是仿照TIdHTTPWebBrokerBridge写一个TSynHTTPWebBrokerBridge,单元名称就叫SynHTTPWebBrokerBridge.pas 这个才是正路吧?
----------------------------------------------
-
作者:
2018/5/24 13:14:37
63楼:
这样做是让原来用Indy通讯控件,并选择GUI服务器界面的改动最小。 无所谓何为正路,何为弯路。 个人认为Server端做成GUI完全没有必要,应该选择Console,或Service用户界面。
----------------------------------------------
-
作者:
2018/5/24 15:58:24
64楼:
支持c5,console好用。
----------------------------------------------
Delphi威武!千秋万代,一统江湖!Delphi威武!千秋万代,一统江湖!Delphi威武!千秋万代,一统江湖!Delphi威武!千秋万代,一统江湖!Delphi威武!千秋万代,一统江湖!Delphi威武!千秋万代,一统江湖!Delphi威武!千秋万代,一统江湖!我去WC吐一会儿去!
作者:
2018/5/24 16:04:18
64楼:
c5soft大帅,我觉得可以做成gui,在现在的服务器,console与gui的性能差异,真有那么大吗? 您的SynWebApp.pas啥时候可以完工呢?我等着它给datasnap rest提质提速呢,您折腾完整后,我愿意付费给您,当然,可能比较微薄。 希望每个使用SynWebApp.pas技术为delphi的三层能够用上http.sys技术的同志都能付费给您。
----------------------------------------------
-
作者:
2018/5/24 16:26:45
65楼:
@sxqwhxq (步惊云) 有您这句话我就很满意了,说明大家对知识产权还是很尊重。 我撸点代码纯粹是图个乐趣,不为钱。之所以没有把自己的代码开源,是没工夫做后续服务。 大家别催,随时关注这个帖子,我会把SynReqRes.pas,SynWebApp,SynHTTPWebBrokerBridge.pas写完。 我真希望哪位大侠对此有兴趣,替我动手,把代码写完了,分享给大家。
----------------------------------------------
-
作者:
2018/5/24 19:01:54
66楼:
无论morMor还kbmMw,使用难度、学习难度都远高于datasnap,但性能稳定性均高于datasnap。如果能让datasnap 乘上http.sys这趟时尚的快车,那么datasnap可用性将大大增强。您的工作意义非凡。
----------------------------------------------
-
作者:
2018/5/24 19:32:35
67楼:
试过datasnap Rest压测内存会涨不掉了,天天来关注下此贴,哈哈
----------------------------------------------
-
作者:
2018/5/24 19:40:29
67楼:
SynBroker 0.0.0.3 版 1.将request/response定义独立出来,放到SynReqRes.pas 2.新增SynHTTPWebBrokerBridge.pas单元,模拟TIdHTTPWebBrokerBridge的功能 3.重构SynWebApp.pas单元 代码在Delphi7,XE,10.2.3(64bit)下编译通过。
----------------------------------------------
-
作者:
2018/5/24 19:49:47
68楼:
感谢c5soft (大道至简)大侠无私的奉献,有这样热心的人,是delphi爱好者的福音。
----------------------------------------------
作者:
2018/5/24 21:03:11
69楼:
请问有办法直接返回stream吗? 如Response.ContentStream := TStringStream.Create('adsfasdfasdfasdfdasf');
----------------------------------------------
-
作者:
2018/5/24 23:45:22
70楼:
等我把SynReqRes.pas写完了,就可以直接返回stream了。 SynBroker 0.0.0.4 版 1.增强SynReqRes.pas实现了Content解析,可以Post了 2.实例代码中增加{$IFDEF MORMOT},方便在mORMot与Indy间切换 3.尚未完全测试,大家帮我找Bug吧
----------------------------------------------
-
作者:
2018/5/25 15:01:03
71楼:
感谢c5soft (大道至简)大侠无私的奉献!
----------------------------------------------
-
作者:
2018/5/25 15:56:55
72楼:
datasnap 推荐服务器与客户端数据交换用json。用流,会有一些错误。
----------------------------------------------
-
作者:
2018/5/25 17:53:00
73楼:
发布SynBroker 0.0.0.5 版,基本可用版 1.增强SynReqRes.pas,实现了输出ContentStream。基本功能全有了。 2.增加SoapClient客户端用例。实现了我个人的目的--让mORMot支持SOAP。 3.在Delphi7/XE/10.2.3三个版本下编译测试通过。Delphi7编译32位的客户端程序SoapClient.exe连接D10.2.3编译的64位的服务程序SynBrokerTestXXX.exe正常运行。 SynBroker呱呱落地,该说声谢谢了。SynBroker是大家的成果,我能把代码写出来离不开以下诸位的支持: 1.mORMot作者AB, Arnaud Bouchez,我敬仰的少数几位大师之一。mORMot这个项目充分体现了作者的工匠精神,是作者将现代软件工程最新理论付诸实践的产物。他简单、高效的风格非常契合我大道至简、美是简单的追求。 2.flier (小海 //爱喝可乐^_^),用中文将WebBroker系统架构刨析得最透彻的那位大咖,他还写了Soap分析,这位学者沉睡近20年的文字为我搞懂Web Broker节省大量时间。 3.Delphi窑洞洞主xalion,他那篇博文是这个项目的导火索。老司机们应该记得,当年51delphi为大家带来了多少福利。 4.本站站长及看帖并回复的朋友,是大家的关注点燃了我写代码的热情。
----------------------------------------------
-
作者:
2018/5/25 18:08:14
74楼:
顶楼上,佩服!真正的程序员,不但有高超的技术,认真钻研的韧劲,还有无私奉献的精神! 谢谢!
----------------------------------------------
-
作者:
2018/5/25 18:20:04
75楼:
虽然不懂,还是要顶一下。
----------------------------------------------
-
作者:
2018/5/25 18:59:00
76楼:
c5soft (大道至简)给现在正热起来的商业三层架构透明化了,使复杂高深的三层架构让更多人都能用起来。 “咱们用Delphi做的东西终于可以与php/timcat/nodejs一争高下,做出7x24永远不宕机的产品。”
----------------------------------------------
作者:
2018/5/25 19:01:56
76楼:
佩服楼主,继续顶!
----------------------------------------------
==========
作者:
2018/5/25 20:49:07
77楼:
感谢c5soft分享!!!!
----------------------------------------------
-
作者:
dunken (dunken)
★☆☆☆☆
-
盒子活跃会员
2018/5/25 21:45:37
78楼:
佩服楼主,继续顶!
----------------------------------------------
-
作者:
omvm ( )
★☆☆☆☆
-
盒子活跃会员
2018/5/25 22:54:11
79楼:
鼓个掌,加下油。
----------------------------------------------
-
作者:
2018/5/25 23:06:37
80楼:
好像.net调用webservice服务的时候中文乱码,delphi的客户端调用没问题。 估计字符还需要特殊处理
此帖子包含附件: 大小: 21.3K
----------------------------------------------
-
作者:
2018/5/26 7:09:32
81楼:
Delphi写Soap服务实在是太方便了,傻子都会写。底层换mORMot后性能与稳定性能够提升,完全可以用Delphi来写WebService了。 用http抓包工具比如HTTPAnalyzer分析一下发出与收到的数据情况,看看.net有什么特殊的要求。用.net服务器对.net客户端的数据流做个对比。就不难找到问题所在了。 delphi返回的soap结果中http报文头部Content-Type: text/xml没有charset标注,完整的应该是:Content-Type:text/xml; charset=UTF-8,是不是这里影响到.net客户端的解读?
----------------------------------------------
-
作者:
2018/5/26 7:37:28
82楼:
很有可能,没仔细分析,测试用datasnap是正常的
----------------------------------------------
-
作者:
szlbz (秋风)
★☆☆☆☆
-
盒子活跃会员
2018/5/26 8:50:43
83楼:
感谢c5soft分享!!!!
----------------------------------------------
-
作者:
2018/5/26 11:32:25
84楼:
可用于datasnap rest环境么?
此帖子包含附件: 大小: 59.8K
----------------------------------------------
-
作者:
2018/5/26 11:51:07
85楼:
用Delphi10.2.3新建一个DataSnap Rest Server,将TIdHTTPWebBrokerBridge替换为TSynHTTPWebBrokerBridge,注释掉 //FServer.Bindings.Clear; //FServer.DefaultPort 编译通过。对DataSnap研究不深,等待有经验的老司机来测试。
----------------------------------------------
-
作者:
2018/5/26 13:43:19
86楼:
第一时间测试了下datasnap rest。 将SynHTTPWebBrokerBridge.pas、SynReqRes.pas、SynWebApp.pas拷入工程目录。 用SynHTTPWebBrokerBridge替代工程中所有IdHTTPWebBrokerBridge; 用 FServer := TSynHTTPWebBrokerBridge.Create(Self);替代 FServer := TIdHTTPWebBrokerBridge.Create(Self); 1、编译时会出现错误:httpsetserviceconfiguration failed:拒绝访问; 2、忽略错误继续,生成的exe比用indy略大,说明http.sys有关代码编译进了工程,但启动exe明显要等待; 3、客户端访问正常,但速度比用indy慢。用jmter 2.11测试,要慢2-3倍。
----------------------------------------------
-
作者:
2018/5/26 13:54:50
87楼:
无论morMor还kbmMw,使用难度、学习难度都远高于datasnap,但性能稳定性均高于datasnap。如果能让datasnap 乘上http.sys这趟时尚的快车,那么datasnap可用性将大大增强。您的工作意义非凡。 你没有好例子,学起来当然觉得难。 亲自体验,kbmmw比datasnap简单易懂。
----------------------------------------------
Delphi 的移动程序开发,是您不可再错失的机遇:http://blog.163.com/you888@188/blog/static/6723961920169319529515/
作者:
2018/5/26 15:01:19
88楼:
@sxqwhxq (步惊云) 底层用mORMot替换Indy,编译出来的exe应该变小才对,下面截图是我对用例的测试结果。SynBrokerTestGUID25.dproj里面有编译条件定义,进入项目属性,到最顶层All Configuration设置,将Condition Defines由MORMOT改成MORMOTx编译出来的就是Indy版本,再改回MORMOT,编译出来的是mORMot版本。下图是delphi 10.2.3 64位Release编译的大小对比。文件没减小,可查看是否在别处还引用了Indy。编译报错也不应该是mORMot带来,好好查查。正常编译的mORMot程序启动速度应该飞快才对。http.sys注册时需要系统权限,建议将vistaAdm.RES资源文件包含在dpr中。至于说连接速度,indy与http.sys我没有让他们pk过,没有发言权。这与服务器运行环境有关,服务器上是什么操作系统?建议上支持http.sys V2的系统,比如win10。 改一下SynHTTPWebBrokerBridge.pas把httpApiServer的队列设置成10000,用64位编译,测一下高并发,看看会不会出现系统崩溃的情况。 FHttpServer.OnRequest := Process; FHttpServer.HTTPQueueLength := 10000; FHttpServer.Clone(256 - 1); 你可劲地X,她再也不喊痛!抗X--这是换底层的根本理由。
此帖子包含附件: 大小: 154.4K
----------------------------------------------
-
作者:
2018/5/26 18:34:37
89楼:
我吵,性能提升了20倍,但错误达到69%? 在jmter中开1000个线程,select xb,xb,csny,mz,commune from tbworker 1000条记录,5个字段,没有图形字段。
此帖子包含附件: 大小: 105.7K
----------------------------------------------
-
作者:
2018/5/26 20:39:31
90楼:
感谢c5soft分享!!!
----------------------------------------------
-
作者:
2018/5/26 21:19:02
91楼:
找到绕开WebBroker直接使用编写Soap WebService的方法了。 把Soap核心组件扣出来,对接到我的框架中,路由代码如下: unit uMapSoap; interface implementation uses HTTPApp, SOAPHTTPPasInv, WebBrokerSOAP, WSDLPub, SynReqRes, uWebServer; function DoDispatch(const Env: TWebEnv; const ADispatcher: IWebDispatch): Boolean; var Request: TSynWebRequest; Response: TSynWebResponse; begin Request := TSynWebRequest.Create(Env.Context); try Response := TSynWebResponse.Create(Request); try Result := ADispatcher.DispatchRequest(nil, Request, Response); finally Response.Free; end; finally Request.Free; end; end; function RouteMapSoapWSDL(const Env: TWebEnv): Boolean; var WSDLPublisher: TWSDLHTMLPublish; begin WSDLPublisher := TWSDLHTMLPublish.Create(nil); try Result:=DoDispatch(Env, WSDLPublisher); finally WSDLPublisher.Free; end; end; function RouteMapSoapPost(const Env: TWebEnv): Boolean; var SoapDispatcher: THTTPSoapDispatcher; PascalInvoker: THTTPSoapPascalInvoker; begin PascalInvoker := THTTPSoapPascalInvoker.Create(nil); SoapDispatcher := THTTPSoapDispatcher.Create(nil); SoapDispatcher.Dispatcher := PascalInvoker; try Result:=DoDispatch(Env, SoapDispatcher); finally SoapDispatcher.Free; PascalInvoker.Free; end; end; initialization RouteMap('GET', '/wsdl', RouteMapSoapWSDL); RouteMap('POST', '/soap', RouteMapSoapPost); end.
----------------------------------------------
-
作者:
2018/5/27 0:35:30
92楼:
这个怎么玩?
----------------------------------------------
-
作者:
2018/5/27 14:41:48
93楼:
1、用ab 测试静态网页(非数据库查询产生的网页),开5000个线程,不挂机; 2、用jmter测试动态网页(从数据库查询产生的网页),开1000个线程,产生大量错误,但不挂机。用indy版本不产生错误;开5000个线程,indy版本挂机,无法测试了,http.sys版本仍然产生大量访问错误,但仍然不挂机。 上面测试,中间件由于使用了较老版本的数据库,因此编译为32位。 看来,用http.sys替代indy,仍须完善。
----------------------------------------------
-
作者:
2018/5/27 17:07:12
94楼:
32位编译高并发必挂机,mORMot也没辙。查查出错原因在哪里,才知道在哪里改进。 我抽空做一个动态页面测试用例,看看万次并发的差错情况。
----------------------------------------------
-
作者:
2018/5/27 17:39:31
95楼:
不是很明白 procedure TSynWebResponse.SendStream(AStream: TStream); var Buffer: SockString; begin SetLength(Buffer, AStream.Size); AStream.Read(Buffer[1], AStream.Size); Context.OutContent := Buffer; end; 这样输出的已经不是stream了吧,看了一下mORMot源码,好像根本没实现ContentStream,也看了一下文档,好像是说用rawutf8效率更高,但总觉得这样来来回回转换效率更低 另外执着于datasnap的理由又是什么呢?用json之类的话直接用mORMot不就好了吗? 俺水平太低没深入研究,请指教
----------------------------------------------
-
作者:
2018/5/27 19:01:56
96楼:
@bayman 问题提得很好。 mORMot的确没提供SendStream。也许http.sys API就没有,没深入研究。但是http.sys提供了直接将文件发送给客户端的功能。如果非要做一个地道的SendStream,mORMot提供的方法是将Stream保存为一个临时文件,将文件名直接发给http.sys: procedure TWebEnv.OutFile(const AFileName: string); var ContentType: RawUTF8; begin Context.OutContent := StringToUTF8(AFileName); Context.OutContentType := HTTP_RESP_STATICFILE; ContentType := InferContentType(AFileName); if Length(ContentType) > 0 then OutHeader(HEADER_CONTENT_TYPE + ContentType); end; 不过SynBroker里的这个办法也是可行的,SockString=RawByteString= Array of Byte,就是字节流,应该是可以将任何东西发给客户端的,配合OutContentType,客户端就可以解析了。 mORMot自带的Rest框架非常好,完全可以取代DataSnap,这样做只是为了给已有DataSnap的项目输送一点新鲜血液。另外,mORMot不支持Soap WebService,而Delphi的Soap写得非常好,没必要重复发明轮子,这个项目很好的补全这项功能。
----------------------------------------------
-
作者:
2018/5/27 21:12:15
97楼:
SynBroker暂时收工,版本号定为0.9.0.0。 SynBroker 0.9.0.0 版,基本稳定版,全部源码 让Delphi WebBroker/DataSnap通讯底层用上mORMot提供的http.sys调用,在Windows坏境实现高并发(万次以上)与高稳定(长期不运行不宕机)。 1.项目文件名以SynWeb开头,不是SynWeb开头的文件都不是必须的。一共4个文件,文件之间的引用关系是:SynWebApp->SynWebServer->SynWebReqRes->SynWebEnv。 2.SynHTTPWebBrokerBridge.pas用于替换IdHTTPWebBrokerBridge.pas,让大家少敲打几次键盘,这个文件中实质只有一行TSynHTTPWebBrokerBridge = TSynWebServer。 3.SynBrokerTest.dpr是Console类型服务端用例程序,SynBrokerTestGUI.dpr是GUI类型服务端用例程序。 4.SoapClient.pas客户端用例程序,用于测试Soap调用。 5.在Delphi7/XE/10.2.3三个版本下编译测试通过。支持Win32位与Win64位编译。 重要的事情要多说几遍,SynBroker能够降生,离不开以下诸位的支持: 1.mORMot作者AB, Arnaud Bouchez,我敬仰的少数几位大师之一。mORMot这个项目充分体现了作者的工匠精神,是作者将现代软件工程最新理论付诸实践的产物。他简单、高效的风格非常契合我大道至简、美是简单的追求。 2.flier (小海 //爱喝可乐^_^),用中文将WebBroker系统架构刨析得最透彻的那位大咖,他还写了Soap分析,这位学者沉睡近20年的文字为我搞懂Web Broker节省大量时间。 3.Delphi窑洞洞主xalion,他那篇博文是这个项目的导火索。老司机们应该记得,当年51delphi为大家带来了多少福利。 4.本站站长及看帖并回复的朋友,是大家的关注点燃了我写代码的热情。
----------------------------------------------
-
作者:
2018/5/27 21:57:58
98楼:
再次感谢c5soft的无私奉献!顶上去
----------------------------------------------
-
作者:
lsuper (lsuper)
★☆☆☆☆
-
盒子活跃会员
2018/5/27 22:36:43
99楼:
强烈建议 c5soft 把这个发到 github 上去 ?
----------------------------------------------
-
作者:
ritapl (ritapl)
★☆☆☆☆
-
盒子活跃会员
2018/5/28 10:18:17
100楼:
强烈建议 c5soft 把这个发到 github 上去! 能把http.sys与webbroker,datasnap完美结合,这本身就是很有意义的一个项目,虽然是洞主最早提出的,但楼主能将之完善,成熟也是功德无量!
----------------------------------------------
-
作者:
2018/5/28 10:33:48
101楼:
github sf.net 都可以。 强烈建议 c5soft 把这个发到 github 上去
----------------------------------------------
(C)(P)Flying Wang
作者:
2018/5/28 10:47:37
101楼:
可能是因为我水平有限,我按楼主的方法用hppt.sys替代datasnap rest中的indy后,改善不大,作用发挥不明显。 1、楼主将FServer的port、Active设为只读,无法在项目中动态设置,只能在源码中指定端口,如果使用默认端口编译不会出错,如果修改源码指定端口,会出现一个编译错误; 2、用jmter模拟500个线程并发访问数据库查询(1000记录、5个字段)错误率为0,1000个线程错误率30%、3000个线程80%错误率。而使用indy1000个线程没有错误,2000个挂机。仔细比较平均访问时间、吞吐量、每秒传送数据,两者差别不大;用ab 测试没有数据库访问的静态网页,5000个并发,两者差别不大。 3、在win2008R2中,查看datasnap http.sys有内存泄漏,这个datasnap indy也有,但泄漏严重些,不过到达一定值以后不再增加(内存使用量、句柄数)。 从主观使用感觉看,无论从手机app还是win32访问http.sys和indy的datasnap rest做的三层,速度、稳定性没有差别,暂时没有体会到飞起来的感觉。 另外,我始终没有证明,这样的三层是否真的使用了morMot的http.sys。
----------------------------------------------
-
作者:
2018/5/28 17:17:14
102楼:
http端口在与可执行文件同名的ini文件中配置: SynWebServer.pas中有: FPort := FIniFile.ReadString('Server', 'Port', '8080'); 自己创建一个与exe同名的INI文本文件,如SynBrokerTest.ini,文件中输入: [Server] Port=80 即将端口改为80
----------------------------------------------
-
作者:
2018/5/28 17:24:31
103楼:
var DefPort: Integer = 8080; FPort := FIniFile.ReadString('Server', 'Port', DefPort); 这样就没问题了。
----------------------------------------------
(C)(P)Flying Wang
作者:
2018/5/28 17:37:28
103楼:
内存泄漏是对于客户端程序而言问题不大,因为运行时间不长,处理完业务就退出了。对于服务端程序,因为要长期运行,这是绝对不能容忍的,可能是致命的。 要想做出7x24小时无故障运行的服务端程序,一定要把内存泄漏彻底消灭。每增加一段代码,就要检查有无内存泄漏,即时解决。 连接mORMot底层,绝对没有内存泄漏的问题! 是不是真的使用了mORMot最简单的方法就是检查生成的exe大小,把indy替换为mORMot后,exe一定变小了才对。 http.sys的性能在Windows各个版本会有差别,尽量使用最新版本的操作系统。
----------------------------------------------
-
作者:
2018/5/28 19:49:41
104楼:
后面这个版本加了content type,但是.net调用还是乱码
----------------------------------------------
-
作者:
dunken (dunken)
★☆☆☆☆
-
盒子活跃会员
2018/5/28 21:26:41
105楼:
感谢c5soft的无私奉献!顶
----------------------------------------------
-
作者:
2018/5/28 23:11:54
106楼:
@delphi_911 要让DotNet能够享用Delphi写的Soap服务,改一下PascalInvoker.Converter的属性,如果还不行只有自己写一个TOPToSoapDomConvert了: TDotNetOPToSoapDomConvert = class(TOPToSoapDomConvert) ... end
此帖子包含附件: 大小: 141.3K
----------------------------------------------
-
作者:
2018/5/29 8:30:25
107楼:
C5SOFT:我编译的http.sys版本比indy版本始终大20K,看来没有用上http.sys。但我把工程中所有使用indy的地方都换了http.sys。
----------------------------------------------
-
作者:
2018/5/29 9:03:05
108楼:
可以参考洞主原文上面,用web测试工具看看是否真的使用了http.sys
----------------------------------------------
-
作者:
2018/5/29 10:47:29
109楼:
@c5soft (大道至简) 谢谢指导,解决.net调用乱码的问题,不过我调整了一下这里编译选项,不然XE7编译不对。 //{$IF (CompilerVersion<20.0) OR (CompilerVersion>30.0) } {$IF CompilerVersion >= 18.5} function UTF8ToWBString(const AVal: RawUTF8): WBString; begin Result := UTF8ToString(AVal); end; function WBStringToUTF8(const AVal: WBString): RawUTF8; begin Result := StringToUTF8(AVal); end; {$ELSE} function UTF8ToWBString(const AVal: RawUTF8): WBString; begin Result := CurrentAnsiConvert.UTF8ToAnsi(AVal); end; function WBStringToUTF8(const AVal: WBString): RawUTF8; begin Result := CurrentAnsiConvert.AnsiToUTF8(AVal); end; {$IFEND}
----------------------------------------------
-
作者:
2018/5/29 10:51:11
109楼:
上面发过64位编译的文件大小对比,再发一个32位编译的文件大小对比,Release编译, 连接mORMot比连接Indy生成exe文件小了将近400K。
此帖子包含附件: 大小: 33.0K
----------------------------------------------
-
作者:
2018/5/29 11:01:37
110楼:
再做一个极端试验 用上面两个32位编译的exe本机对本机做压力测试,排除网络连接速度的影响,1000个并发,做50000次测试: ab -n 50000 -c 1000 http://127.0.0.1:8080/ 结果mORMot比indy快100倍。这是极端情况,静态文件,不连数据库,实际项目中不可能差这样多。较慢的网络速度与数据库速度把总体速度拉下来了。
此帖子包含附件: 大小: 672.2K
----------------------------------------------
-
作者:
2018/5/29 11:18:48
111楼:
我有一个投入运营的生产项目,经历了从IntrawWeb换成Nodejs, 又从nodejs换成WebBroker ISAPI(http.sys),再由WebBroker ISAPI(http.sys)换成mORMot(http.sys)的过程。因为IntraWeb用的是Indy,相当于是从Indy换成了mORMot。从indy换成http.sys,系统的运行速度、稳定性与用户体验的改善是非常显著的。 由WebBroker ISAPI(http.sys)换成mORMot(http.sys),主要是让软件调试、发布及后期维护变得容易多了,再也不用去折腾IIS了。速度没有什么变化。
----------------------------------------------
-
作者:
2018/5/29 12:30:42
112楼:
c5soft大神,新手想问一下:这个能用于C/S吗?
----------------------------------------------
-
作者:
2018/5/29 13:05:22
113楼:
DataSnap不就是C/S吗?不用Delphi的,用mORMot自带的Rest也行。
----------------------------------------------
-
作者:
yaoyl (云里雾里)
★☆☆☆☆
-
盒子活跃会员
2018/5/29 21:51:00
114楼:
感谢c5soft的无私奉献!
----------------------------------------------
Delphi老菜鸟~
作者:
2018/5/29 22:36:18
115楼:
希望C5Soft大帅能够仔细分析一下在datasnap 和datasnap Rest中的应用,因为datasnap是emb力推的多层工具,用http.sys改进这并不要您深究datasnap工作机制,因为您对webbroke技术很了解,很容易就能做到,希望您重视一下这个很有意义的工作。我确实完全是按您的步骤做的,您介绍是步骤并不复杂,用您的单元替代原来的indy单元而已,但确定没效果,而且稳定性大幅降低。 另外,我的morMot版本是1.18。
----------------------------------------------
-
作者:
2018/5/30 8:40:38
116楼:
@sxqwhxq 因为没有你具体的出错信息。我猜你的报错很大的可能性瓶颈不在http.sys,而在数据库查询上。用上了http.sys,还是要继续优化其他配套部分的。
----------------------------------------------
-
作者:
2018/5/30 9:30:51
117楼:
sxqwhxq 为什么不提供一下简单的例子让我们大家试试呢?如果单纯用于数据库操作,数据库成为瓶颈,HTTPSys优势不是特别明显,HTTPSys更稳定,电脑的资源利用有区别。再次感谢C5Soft无私奉献!
----------------------------------------------
-
作者:
gyh75 (ggg)
★☆☆☆☆
-
盒子活跃会员
2018/5/30 13:15:08
118楼:
delphi开发的相关系统,大家可以关注下。 上位机开发之家:http://shangweiji.lofter.com
----------------------------------------------
-
作者:
2018/5/31 14:52:31
119楼:
目前,mOrMot包装的http.sys技术可以部分用于datasnap REST,从jmter2.11测试的报文已经有morMot公司的信息,反复测试表明性能有40%左右提升,而且内存泄漏比indy版本的datasnap有很大改善。 但只能部分用于datasnap rest,性能改善有限,原因在于rest关键组件TDSHTTPWebDispatche是根植于indy的,这个暂时没法剥离出来。 只能期待窑洞洞主出手了。
----------------------------------------------
-
作者:
2018/5/31 21:38:42
120楼:
119楼,你对datasnap这么感冒吗?拿钱去砸窑洞洞主试试先
----------------------------------------------
-
作者:
dunken (dunken)
★☆☆☆☆
-
盒子活跃会员
2018/6/1 20:22:03
121楼:
顶
----------------------------------------------
-
作者:
2018/6/8 12:41:06
122楼:
大力顶,能看到神一样的C5,真是荣幸!C5在哪个城市呀?
----------------------------------------------
-
作者:
vga (vga)
★☆☆☆☆
-
盒子活跃会员
2019/1/2 10:28:37
123楼:
感谢c5soft的无私奉献!好贴不能沉呀!继续顶!!!
----------------------------------------------
-
作者:
2019/1/16 21:58:49
124楼:
2.发送自定义头如果Name相同,使用Response.SetCustomHeader(name,value),发送到浏览器的时候只有最后一个 ·比如:Response.SetCustomHeader('test','test1'); Response.SetCustomHeader('test','test2'); Response.SetCustomHeader('test','test3'); 那么发送到浏览器的时候只有test:test3 ·如果使用Response.CustomHeaders.Add(str)->Response.CustomHeaders.Add(Name+'='+Value)则没有问题 3.响应多个Cookie只会发送最后一个set-cookie例如: with Response.Cookies.Add do begin name:='cookie1'; value:='cookie1'; end with Response.Cookies.Add do begin name:='cookie2'; value:='cookie2'; end with Response.Cookies.Add do begin name:='cookie3'; value:='cookie3'; end 只会发送Set-Cookie:cookie3=cookie3 解决办法如下 mORMot的SynCrtSock单元HTTP_RESPONSE.AddCustomHeader(P: PAnsiChar; var UnknownHeaders: HTTP_UNKNOWN_HEADERs; ForceCustomHeader: boolean): PAnsiChar; 把 const KNOWNHEADERS: array[reqCacheControl..respWwwAuthenticate] of PAnsiChar = ( 'CACHE-CONTROL:','CONNECTION:','DATE:','KEEP-ALIVE:','PRAGMA:','TRAILER:', 'TRANSFER-ENCODING:','UPGRADE:','VIA:','WARNING:','ALLOW:','CONTENT-LENGTH:', 'CONTENT-TYPE:','CONTENT-ENCODING:','CONTENT-LANGUAGE:','CONTENT-LOCATION:', 'CONTENT-MD5:','CONTENT-RANGE:','EXPIRES:','LAST-MODIFIED:', 'ACCEPT-RANGES:','AGE:','ETAG:','LOCATION:','PROXY-AUTHENTICATE:', 'RETRY-AFTER:','SERVER:','SET-COOKIE:','VARY:','WWW-AUTHENTICATE:'); 'SET-COOKIE:'改为''即可解决问题 4.SynWebReqRes单元OutCookiesAndCustomHeaders函数,//HeaderValue方法取得string是 经过URLEnCode的 空格会被转义为+ Env.OutHeader(StringToUTF8('Set-Cookie: ' + GetHeaderValue(Cookies[i]))); 修改为 Env.OutHeader(StringToUTF8('Set-Cookie: ' + URLDecode(Cookies[i].HeaderValue)));
----------------------------------------------
草籽天涯
作者:
2019/1/17 10:17:31
125楼:
请高手看下,D10.2.1这里编译不通过是怎么个问题??morMor下的是最新的。
此帖子包含附件: 大小: 10.7K
----------------------------------------------
-
作者:
2019/1/24 8:30:27
126楼:
赞一个
----------------------------------------------
-
作者:
2019/8/21 18:16:50
127楼:
我用带ssl的https总是失败
----------------------------------------------
-
作者:
vga (vga)
★☆☆☆☆
-
盒子活跃会员
2019/12/19 10:20:22
128楼:
好帖莫沉呀!!!
----------------------------------------------
-
作者:
ww66 (wzs)
★☆☆☆☆
-
普通会员
2019/12/19 21:05:35
129楼:
好,多谢
----------------------------------------------
http://www.inteLw.cn:8077
作者:
sumig (sumig)
★☆☆☆☆
-
盒子活跃会员
2020/1/9 8:28:43
130楼:
雖然看得不是很懂,還是多謝樓主無私的奉獻!
----------------------------------------------
-
作者:
2020/1/9 17:05:30
131楼:
mark 学习一下
----------------------------------------------
浪迹软件 开源WKE4DELPHI
作者:
2020/1/9 21:53:59
132楼:
WebBroker 是好东西,掌握了 WebBroker 就掌握了 http 的工作原理。
----------------------------------------------
-
作者:
joman (joman)
▲▲▲▲▲
-
普通会员
2020/1/20 10:05:50
133楼:
楼主的东西确实是好东西,有了楼主的东西才让delphi 开发web 成为可能。 是否使用了mormot 可以这样查看 浏览器访问接口F12 查看
----------------------------------------------
DelphiWeb开发方案(开源):https://gitee.com/pearroom/DelphiWebMVC
作者:
2021/1/14 17:10:57
134楼:
楼主大神的这个是个好器,难搞啊。 怎么Post不能取到值,奇怪了 procedure TWebModule1.WebModule1WebActionItemPostAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); var cName, cPhone: string; begin cName := Request.QueryFields.Values['name']; //--这里取不到值 cPhone := Request.QueryFields.Values['phone']; {$IFDEF MORMOT} Response.ContentType := 'text/html; charset=utf8'; // 让汉字正确显示 {$ENDIF} Response.Content := cstHTMLBegin + RequestInfo(Request) + '<p>Name:' + cName +'</p>' + '<p>Phone:' + cPhone +'</p>' + '<a href="/?' + Request.Content + '">返回</a>' + cstHTMLEnd; end; ---另外让汉字正常,可以在定义 cstHTMLBegin = '<HTML><meta charset="utf-8"><BODY>'上加上utf-8,这样就不会乱码
----------------------------------------------
没有比没有更没有
作者:
2021/1/14 17:14:00
135楼:
WebBroker 是个好东西
----------------------------------------------
-
作者:
2022/1/23 11:01:00
138楼:
这两天在看delphiwebmvc,看到底层用的c5soft大仙的通讯, 请问c5soft (大道至简)大仙能否传下最新版的synbroker? 感谢
----------------------------------------------
delphi加油!!
作者:
2023/7/5 22:42:00
139楼:
感谢c5soft的无私奉献!好贴不能沉呀!继续顶!!! mORMot2 下可以用吧?
----------------------------------------------
-
作者:
2023/7/6 8:06:46
140楼:
用rtc吧,开源、跨平台,稳定高并发。
----------------------------------------------
-
作者:
2023/7/7 14:52:59
141楼:
sxqwhxq (步惊云) rtc 比 mOrMot 更好?
----------------------------------------------
-
作者:
2023/7/8 9:47:52
142楼:
我对mORMot没兴趣,没做过对比。我对 rtc有个粗浅的应用,感觉真的很不错。
----------------------------------------------
-