DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: hxh57738897
今日帖子: 24
在线用户: 25
导航: 论坛 -> Web应用开发 斑竹:bodies  
作者:
男 c5soft (大道至简) ▲▲▲▲▲ -
普通会员
2018/6/1 21:09:08
标题:
使用http.sys,让delphi的多层服务真的飞起来【第二部】 浏览:17048
加入我的收藏
楼主: 这是本专题的续集,没读过第一部的看这里:
http://bbs.2ccc.com/topic.asp?topicid=548153

之所以要搞第二部是因为第一部跟贴太多,读起来不方便,浪费大家的时间。

今天咱们聊的主题是:Delphi的DataSnap实质分析
先说DataSnap中文应该翻译成什么,我个人的译法是:数据快照。
大家不要被这么多介绍DataSnap的资料弄晕了,其实原理非常简单。
要把DataSnap搞明白,必须先把客户端的TClientDataset控件搞明白,不会,找度娘。下面简称CDS。
CDS有两个OleVarient属性,一个叫Data,一个叫Delta。Delphi的多层框架全靠这哥俩。Data用于客户端从服务器端获取数据,Delta用于客户端将修改的数据保存到服务器端。
那么,这就简单了,服务器端只要能实现输出Data,接收Delta,三层应用就搞起来了。服务器端这项工作安排给谁呢?TDatasetProvider,下面简称DP。
DP有一个Data属性,也是OleVariant类型,还有一个ApplyUpdate方法,接受Delta作为输入参数。
----------------------------------------------
-
作者:
男 c5soft (大道至简) ▲▲▲▲▲ -
普通会员
2018/6/1 21:30:28
1楼: 明白了这个道理,我们完全可以抛开Delphi那个复杂的DataSnap不理,自己来构建简单可靠而且高效的多层框架。
服务器端自然用mORMot来稿,用THttpApiServer+DP,充分发挥http.sys的威力,站在巨人的肩膀上,呼风唤雨。
客户端我们用Delphi10.2.3来做,支持PC/Android/iOS, 用CDS+TNetHTTPRequest来做。
不考虑手机的,继续用Delphi7做PC应用的铁粉,用CDS+THttpClientSocket(mORMot自带)。
----------------------------------------------
-
作者:
男 c5soft (大道至简) ▲▲▲▲▲ -
普通会员
2018/6/1 21:32:56
2楼: Data与Delta都是Variant,无法在网络上传输,我们需要这俩变成字符串,先来两个函数:

{$IFNDEF UNICODE}
type
  RawByteString = AnsiString;
{$ENDIF}

function VariantArrayToString(const V: OleVariant): RawByteString;
var
  P: Pointer;
  Size: Integer;
begin
  Result := '';
  if VarIsArray(V) and (VarType(V) and varTypeMask = varByte) then begin
    Size := VarArrayHighBound(V, 1) - VarArrayLowBound(V, 1) + 1;
    if Size > 0 then begin
      SetLength(Result, Size);
      P := VarArrayLock(V);
      try
        Move(P^, Result[1], Size);
      finally
        VarArrayUnlock(V);
      end;
    end;
  end;
end;

function StringToVariantArray(const S: RawByteString): OleVariant;
var
  P: Pointer;
begin
  Result := NULL;
  if Length(S) > 0 then begin
    Result := VarArrayCreate([0, Length(S) - 1], varByte);
    P := VarArrayLock(Result);
    try
      Move(S[1], P^, Length(S));
    finally
      VarArrayUnlock(Result);
    end;
  end;
end;
----------------------------------------------
-
作者:
男 c5soft (大道至简) ▲▲▲▲▲ -
普通会员
2018/6/1 21:40:24
3楼: 看明白了吗?Data与Delta内部存储的都是字节流。变成字节流以后有两种传送方式,一种是以Stream方式,ContentType设置成application/octet-stream;另一种将字节流base64编码成纯文本。大数据流可以加入压缩/减压机制,保密数据可以加入加密/解密机制。
----------------------------------------------
-
作者:
男 snakegao (snakegao) ★☆☆☆☆ -
盒子活跃会员
2018/6/1 21:44:52
3楼: 大侠开坛讲授,谢谢啦,收藏!!!
----------------------------------------------
-
作者:
男 c5soft (大道至简) ▲▲▲▲▲ -
普通会员
2018/6/1 21:48:30
4楼: base64编码与解码,Delphi自带,单元名为EncdDecd。里面有EncodeString与DecodeString两个函数。


为了让大家把原理搞懂,我们先抛开网络传输层,将CDS与DP放在一个屋子里让他俩亲热一把。

procedure TForm2.Button1Click(Sender: TObject);
var
  vDataIn, vDataOut: OleVariant;
  cDataIn, cDataOut: RawByteString;
begin
  ClientData.Close;
  vDataIn := ServerDataSetProvider.Data;
  cDataIn := VariantArrayToString(vDataIn);

  //模拟网络传送
  cDataOut:=cDataIn;

  vDataOut := StringToVariantArray(cDataOut);
  ClientData.Data := vDataOut;
end;

附完整源代码,在Delphi7/XE/10.2.3下编译
此帖子包含附件:c5soft_20186122281.rar 大小:464.8K
----------------------------------------------
-
作者:
男 c5soft (大道至简) ▲▲▲▲▲ -
普通会员
2018/6/1 22:57:19
5楼: 我这里转载了一篇文章细说CDS的用法:
https://www.cnblogs.com/c5soft/p/9121775.html

没仔细看过手机版的CDS,不知道是不是完全实现了PC版的功能,用过的朋友多发帖。
----------------------------------------------
-
作者:
男 c5soft (大道至简) ▲▲▲▲▲ -
普通会员
2018/6/1 23:17:18
6楼: 说点题外话,CDS鼠标右键菜单有一项“Assign Local Data...”,可以将相同窗体上的任何TDataset的数据复制到CDS中,如何实现的呢?我猜想就是用到了DP, 应该是这样写的:

var DP:TDatasetProvider;
begin
  DP:=TDatasetProvider.Create;
  DP.Dataset=ADODataset1;
  ClientDataset1.Data:=DP.Data;
  DP.Free
end;
----------------------------------------------
-
作者:
男 c5soft (大道至简) ▲▲▲▲▲ -
普通会员
2018/6/1 23:37:10
7楼: 发一个TNetHTTPRequest的用例,这个控件的用法在Delphi的文档中找不到例子,看了一下windows下调用的dll,没看到WinINet的影子,倒是看到Winsock.dll了,如是,性能应该不错的。

源代码在Delphi10.2.3下编译,低版本的Delphi应该没有这个控件,具体是哪个版本开始有,我没研究过,知道的朋友请发帖。
此帖子包含附件:c5soft_201861233710.zip 大小:8.0K
----------------------------------------------
-
作者:
男 biznow (biznow) ★☆☆☆☆ -
盒子活跃会员
2018/6/1 23:52:07
8楼:  c5soft 大侠,热心 且 钻研精神 为 D 传承发光发热,辛苦。
----------------------------------------------
-
作者:
男 homejun (homejun) ★☆☆☆☆ -
盒子活跃会员
2018/6/2 4:51:31
9楼: 期待官方datasnap升级到http.sys
----------------------------------------------
-delphi新资讯站 http://www.delphigear.cn
作者:
男 ritapl (ritapl) ★☆☆☆☆ -
盒子活跃会员
2018/6/2 8:15:13
10楼: 有WebBroker + http.sys就足够用了!
----------------------------------------------
-
作者:
男 hnxxcxg (咏南中间件) ★☆☆☆☆ -
盒子活跃会员
2018/6/2 9:05:21
11楼: 此种方式,如果中间件和客户端都是DELPHI来开发的话,确实是既简单又方便。
然而,如果客户端是别的开发语言的话,就不大适用。
----------------------------------------------
中间件QQ群: 92449782 博客: http://www.cnblogs.com/hnxxcxg/
作者:
男 sxqwhxq (步惊云) ★☆☆☆☆ -
普通会员
2018/6/2 10:06:11
12楼: 为了不占用篇幅,我只提一个问题,希望大家也慎重跟贴,不影响大师授课:
用mOrMot做服务器性能优异,但morMot封装程度低,学习难度高。例如,如何进行会话管理,在datasnap中,datasnap用ServerMethods单元管理会话,
TServerMethods其实是一个数据模块,上面放数据连接、数据访问等不可视组件,如FdConnect、FdQuery、FDMemTable等组件,用于与数据库、客户端连接和交互数据。一个连接产生一个TServerMethods实例,譬如,A客户向TServerMethods上的FDquery发送sql语句:select * from tbddress where address='长沙市'、B客户发送sql语句:select * from tbaddress where address='中山市',TServerMethods会自动产生两个不同实例,保证向A、B查询反馈正确的查询结果集。因此,开发者无须为管理session操心,TServerMethods会以最低的资源最高的效率管理客户端会话。不知morMot如何做这个工作,请大帅指导!
----------------------------------------------
-
作者:
男 msfm (清洁工) ★☆☆☆☆ -
盒子活跃会员
2018/6/2 10:21:20
13楼: 板凳看大佬互怼 确实快速开发
----------------------------------------------
-
作者:
男 zhuzh_yuy (华) ★☆☆☆☆ -
普通会员
2018/6/2 10:22:43
14楼: 顶一个
----------------------------------------------
-
作者:
男 hnxxcxg (咏南中间件) ★☆☆☆☆ -
盒子活跃会员
2018/6/2 14:10:44
15楼: 9楼,DATASNAP是不大可能会用HTTPS.SYS作为HTTP通信的。事实上INDY(阻塞型SOCKET)通信足以应付95%的应用场合,且编程至简。
12楼,MORMOT本身已经封装有HTTP SESSION。
13楼,技术是交流,不是互怼,没有什么热闹可以围观。
另外,MORMOT是HTTP和WEBSOCKET封装,没有TCP、UDP封装,有它适合的应用场合。相反INDY对通信协议的封装是比较全面的。DATASNAP使用INDY不是没有考量的。
----------------------------------------------
中间件QQ群: 92449782 博客: http://www.cnblogs.com/hnxxcxg/
作者:
男 sxqwhxq (步惊云) ★☆☆☆☆ -
普通会员
2018/6/2 15:20:14
16楼: 楼上,datasnap Rest经过C5Soft用http.sys的改进,性能和稳定性有很大的提升。
1、indy版本的datasnap Rest只能稳定在500-1000个并发数据库查询,高了会出现大量连接错误,直至out of Memory,用http.sys改进后,5000个并发数据库查询没问题,一个错误也没有;
2、indy版本的datasnap Rest有明显的内存泄漏,大量并发查询(1000个线程)完成后,在win2008R2上内存工作设置增量、专用工作集、提交大小及句柄数会大量增长,表明占用的资源很多没释放,但用http.sys改进后(5000个线程)也只有少量增长,内存和资源占用改善非常明显。
3、我对比了高勇同学给我用最新版本做的kbmMW做的测试中间件和我做的经过改进后的datasnap rest做的中间件,性能,错误率、稳定性、并发数似乎非常接近,速度略差。表明datasnap rest经http.sys改进后,性能接近kbmMW最新版本。
上述测试是在jmter 2.11中进行的,这个测试软件当动态查询并发超过5000后会闪退,否则10000个并发也没问题。
----------------------------------------------
-
作者:
男 hnxxcxg (咏南中间件) ★☆☆☆☆ -
盒子活跃会员
2018/6/2 15:44:12
17楼: 事实上REST我也是用mormot的https.sys作通信。
阻塞型SOCKET大约支持1千左右的TCP长连接。
楼上:
1)500-1000个并发数据库查询,应该更正为500-1000个TCP长连接客户端。
2)http.sys改进后(5000个线程),应该更正为5000个http客户端,HTTPS.SYS是异步SOCKET,中间件不会为每一个http客户端创建一个工作线程来服务。
总之,所谓的并发和长连接是俩码事,不要混为一谈。
另外:
许多客户端数量多的应用场合,其实是可以用TCP短连接的,不一定非要用TCP长连接,在这种时候,INDY应付上千客户端是没有问题的。
----------------------------------------------
中间件QQ群: 92449782 博客: http://www.cnblogs.com/hnxxcxg/
作者:
男 c5soft (大道至简) ▲▲▲▲▲ -
普通会员
2018/6/2 17:00:07
18楼: 发布:SynBroker 0.9.1.0 版,双路由版,全部源码

+1.增加SynWebUtils.pas文件,提供OleVariantArray与RawByteString相互转换,客户端与服务器端都要用到。
+2.修改SynWebEnv.pas文件,在TSynWebEnv中增加FQueryFields属性,用于获取QueryString中的栏目值,增加FContentFields属性,用于获取Form上传栏目值。
+3.修改SynWebEnv.pas文件,增加RouteMap函数用于路由注册,增加RouteDispatch函数用于路由委派。
*4.修改SynWebServer.pas文件,在Process函数体内增加对RouteDispatch的调用,实现非WebBroker路由委派,加上原有的WebBroker路由,实现了双路由。
+5.增加客户端DataClient.dpr与服务器端的uMapDatsTest.pas单元配合演示TClientDataSet与TDatasetProvider配合实现多层应用数据交互。
此帖子包含附件:c5soft_2018621706.rar 大小:537.7K
----------------------------------------------
-
作者:
男 jjwwang (jjwwang) ★☆☆☆☆ -
普通会员
2018/6/2 17:11:05
18楼: 先说下是不是一定要从datasnap+indy变为datasnap+http.sys?

如果当前用datasnap+indy没有性能问题,就可以继续用。
如果想做的更有效率或更具迸发性,可能更多的是针对WEB客户端。
但是,即使是datasnap+http.sys ,如果不服务端设计的不好,或者仅仅是发送sql到服务端取数据,我觉得很多时候会达不到预期的效果。

从datasnap+indy到datasnap+http.sys,本质是通信层的改变。
有状态的Server目前是反对的,推荐的是让服务端无状态。
为了方便WEB端的调用(或者说为了通用性),datasnap使用JSON封装数据。
楼主在前几楼说了那么多,我觉很好的证明了datasnap使用http协议时,客户端是什么根本不重要,重要的是如何打包和解析数据。

说到这里,忽然想问一句:
datasnap+http.sys和iis还有差别吗?如果有,差别是什么?
----------------------------------------------
学无止境
作者:
男 jjwwang (jjwwang) ★☆☆☆☆ -
普通会员
2018/6/2 17:19:37
19楼: 刚回复完,发现楼主又更新了源代码,楼主为datasnap的底层的改善做了重要工作,觉得有必要给楼主点个赞。
----------------------------------------------
学无止境
作者:
男 c5soft (大道至简) ▲▲▲▲▲ -
普通会员
2018/6/2 17:29:02
19楼: SynBroker 0.9.1.0 在Delphi7/XE/10.2.3下编译通过。SynBrokerTest/SynBrokerTestGUI启动后,可以在浏览器上地址栏输入:http://127.0.0.1:8080/datatest?base64=1
测试服务器端DP数据输出是否正常。Base64编码与解码使用的是mORMot的函数BinToBase64/Base64ToBin。

以这个版本作为基础,可开发出多种服务集中在一起的服务应用,同时支持B/S架构与C/S架构,对于非Delphi的前端,也可直接输出JSON/XML数据。
关键是简单,服务通过路由注册添加,即在dpr中包含更多的uMapXXX.pas文件增加服务器功能。大家仔细分析RouteMap函数与RouteDispatch函数就能把路由注册与委派搞明白。
----------------------------------------------
-
作者:
男 c5soft (大道至简) ▲▲▲▲▲ -
普通会员
2018/6/2 17:47:38
20楼: 实际上这个版本是我自己在mORMot基础上开发的c5softWeb框架的简化版,核心思想都体现在这个版本中了。c5softWeb框架是一个非WebBroker框架,已经稳定商用。因为要增加Soap功能,而mORMot已申明不支持Soap, 才来研究WebBroker。对于不喜欢WebBroker的朋友,可以把SynWebServer.pas适当改动,去掉WebBrokerDispatch。这个版本中CDS/DP功能是非WebBroker路由。我在这个系列第一部中公布的Soap路由源代码也是一个非WebBroker路由版。
----------------------------------------------
-
作者:
男 c5soft (大道至简) ▲▲▲▲▲ -
普通会员
2018/6/2 18:17:23
21楼: @jjwwang
用上mORMot的httpsys,对接上DataSnap,性能与稳定性与IIS+WebBrokerISAPI相同,主要是简化了调试与发布难度,改用c5soft松耦合路由,进一步降低了搭建web服务的难度。
----------------------------------------------
-
作者:
男 ccxpts (渔夫) ★☆☆☆☆ -
普通会员
2018/6/3 10:33:17
22楼: TClientDataSet与TDatasetProvider这种方式已经落伍了,在处理MySQL5.6开始就有错误,还是改用fdMemtable吧
----------------------------------------------
-
作者:
男 dunken (dunken) ★☆☆☆☆ -
盒子活跃会员
2018/6/3 16:29:57
23楼: 前一段时间是RTC热,现在是MORMOT 
顶一个 DELPHI 越来越火
----------------------------------------------
-
作者:
男 sxqwhxq (步惊云) ★☆☆☆☆ -
普通会员
2018/6/3 21:25:55
24楼: 建议还是用firedac结合datasnap rest比较好。
----------------------------------------------
-
作者:
男 bsanlang (sanlang) ★☆☆☆☆ -
普通会员
2018/6/4 10:47:12
25楼: datasnap是rpc的通信框架, clientdataset是数据序列化的一种形式。
----------------------------------------------
-
作者:
男 edwinyeah (Edwin) ★☆☆☆☆ -
盒子活跃会员
2018/6/4 12:01:29
26楼: 支持楼主,虽然自己用不上。可否建议楼主创建个github仓库?好向英文论坛介绍介绍嘛。
----------------------------------------------
-
作者:
男 snakegao (snakegao) ★☆☆☆☆ -
盒子活跃会员
2018/6/5 19:15:27
27楼: 继续关注C5soft的动向!!!
----------------------------------------------
-
作者:
男 c5soft (大道至简) ▲▲▲▲▲ -
普通会员
2018/6/6 15:21:54
28楼: 今天咱们说点题外话。做Web服务,后台数据库控件用哪个最好?
UniDAC ? No
FireDAC ? No
dbExpress ? No
dbGO ? No

都不是,用哪个?我给的答案是 SynDB、 ZEOS 或 ADOInt。
为什么不是上面那几位?原因很简单,服务端数据库控件要轻量,要简单.
上述各位都派生自TDataset,而TDataset是为绑定数据控件设计的。
走的是这条线路:TDataset->TDataSource->TDBGrid/TDBEdit
TDataset框架中附加了许多后台数据服务完全用不着的东西。

后台数据服务应该走这条线路:IConnection->IStatement->IResultSet
没错,都是接口,这是ZEOS的设计,不管是SQL Server还是Oracle,操作都一样。

SynDB是mORMot提供的,ZEOS也是一套开源控件,ADOInt一直跟随着我们身边,却被我们忽略了。今天咱们重点说说ADOInt。

ADOInt就是Delphi自带的一个单元文件,从Delphi7以前到最新的10.2.3都有。就是Windows系统自带MSADOMD.DLL的Type Lib库导入文件, 大名叫Microsoft ActiveX Data Object,ADOInt=ADO Interface。这可不是大家熟悉的ADODB即dbGO,是ADODB的底层。使用_Connetion/_Command/_Recordset来操作数据库。

这样做的好处有三个:速度更快,bug更少,exe文件更小。
用ADOInt,我们实际上在用微软,靠得住。如果后台用SQL Server数据库,优先考虑ADOInt, 如果是Oracel/MySQL, 推荐大家用ZEOS。

附加一个微软的ADO使用速查手册,chm格式,有点老,能用,也没有更新的了。
此帖子包含附件:c5soft_201866152153.rar 大小:1.75M
----------------------------------------------
-
作者:
男 c5soft (大道至简) ▲▲▲▲▲ -
普通会员
2018/6/6 15:35:32
29楼: 发一个ZEOS 7.3 OleDB pk ADOInt的图,ADOInt比ZEOS Oledb快20%,64位编译,exe小900K。万次并发,百万次连接。
此帖子包含附件:
JPEG 图像
大小:273.7K
----------------------------------------------
-
作者:
男 bsanlang (sanlang) ★☆☆☆☆ -
普通会员
2018/6/6 23:47:16
30楼: 我们一直用ADOInt在win10上一直有性能问题,换了Unidac的直连模式性能大大提升,也更稳定。
----------------------------------------------
-
作者:
男 ivvn (奔腾的心) ★☆☆☆☆ -
普通会员
2018/6/7 4:15:59
31楼: 两个小问题

1.服务器端好像cookie会有传不到浏览器问题

2.Context.Response.SetContentStream
方法发送流不行
----------------------------------------------
-
作者:
男 c5soft (大道至简) ▲▲▲▲▲ -
普通会员
2018/6/7 8:06:13
32楼: @sanlang
AdoInt的实质是Oledb,性能取决于oledb驱动程序,如果是Oracle数据库,网传oledb驱动速度不行,没测过,推荐用ZEOS, 用Oracle InstantClient,走OCI,性能应该最佳。
----------------------------------------------
-
作者:
男 c5soft (大道至简) ▲▲▲▲▲ -
普通会员
2018/6/7 8:26:48
33楼: @ivvn (奔腾的心)

uses SynWebEnv;

const
  cstCookieIDForSession = 'WEBSERVER_SID';

function RouteMapTestCookie(const AEnv: TSynWebEnv): Boolean;
var cCookie,cSessionID:RowUTF8; 
begin

//读来自浏览器的Cookie:
  cCookie:=AEnv.GetHeader('COOKIE:');
  cSessionID := AEnv.GetHeader(cstCookieIDForSession + '=', cCookie, ';');
//拿到SessionID后就用SessionID去数据库中去状态数据了  
...
//拿不到SessionID,就生成一个,写Cookie发送回到浏览器
if Length(cSessionID) = 0 then begin
  cSessionID := GetRandomString(15);
  AEnv.OutHeader('Set-Cookie: ' + cstCookieIDForSession + '=' + StringToUTF8(cSessionID);
  ...  
end
//发送流,这样写:
  AEnv.OutStream(...)
...
end;

initialization
  RouteMap('GET', '/TestCookie', RouteMapTestCookie);
----------------------------------------------
-
作者:
男 ivvn (奔腾的心) ★☆☆☆☆ -
普通会员
2018/6/7 14:58:27
34楼: constructor TSynWebRequest.Create(const AEnv: TSynWebEnv);
begin
  FEnv := AEnv;
  CookieFields.Text := Trim(FEnv.GetHeader('COOKIE:'));
  inherited Create;
end;

这样交给服务器
----------------------------------------------
-
作者:
男 ivvn (奔腾的心) ★☆☆☆☆ -
普通会员
2018/6/7 14:59:34
35楼: 服务器传回时也要处理一下
还有文件时间问题,现在文件是不缓存的
----------------------------------------------
-
作者:
男 c5soft (大道至简) ▲▲▲▲▲ -
普通会员
2018/6/7 16:11:01
36楼: @ivvn
前面获取Cookie的写法是不用WebBroker,用RouteMap/RouteDispatch的方法,如果要用WebBroker, 在0.9.1.0版的TSynWebRequest中已经实现了Cookie从Http头部到FCookieFields传递了,不需要也不能写成:
CookieFields.Text := Trim(FEnv.GetHeader('COOKIE:'));

你去读一下TWebRequest的源代码就知道了:
GetCookieFields->ExtractCookieFields->Cookie->index 27 read GetStringVariable

GetStringVariable在TWebRequest中override了,当index=27即cstInHeaderCookie 有:
  end else if Index = cstInHeaderCookie then begin
    Result := UTF8ToWBString(FEnv.GetHeader('COOKIE:'));

进一步查了一下TWebResponse里面的FCookie:TCookieCollection,在0.9.1.0版没有将FCookie的值写回Context.OutCustomHeaderss里,算是Bug, 将在后续版本中更正。拿到新版前请用上面介绍的方式回写到浏览器。

要在浏览器端实现静态文件缓存,服务器端需要在HTTP Response头中写点东西。有三种方法:Last-Modifed/ETag/Cache-Control。SynBroker当前版本没有静态文件服务功能,可模仿mORMot的例子自行添加,并在头部加上缓存机制相关信息。
----------------------------------------------
-
作者:
男 c5soft (大道至简) ▲▲▲▲▲ -
普通会员
2018/6/7 20:55:16
37楼: 发布:SynBroker 0.9.2.0 版,双路由版,全部源码

*1.修改SynWebReqRes.pas文件,让TSynWebResponse能够处理回写到Cookie与CustomHeaders
*2.修改TSynWebServer.pas文件,如TSynWebResponse.SendRedirect干活
此帖子包含附件:c5soft_201867205516.rar 大小:561.8K
----------------------------------------------
-
作者:
男 ivvn (奔腾的心) ★☆☆☆☆ -
普通会员
2018/6/7 22:39:50
38楼: function TSynWebResponse.GetContent: WBString;
begin
  Result := UTF8ToWBString(Context.InContent); //这里应该是out吧
end;
----------------------------------------------
-
作者:
男 ivvn (奔腾的心) ★☆☆☆☆ -
普通会员
2018/6/7 22:55:01
39楼: c5大神在mormot群里吗?


加个qq吧
----------------------------------------------
-
作者:
男 c5soft (大道至简) ▲▲▲▲▲ -
普通会员
2018/6/8 8:38:15
40楼: SynBroker 0.9.2.1 版,双路由版,全部源码
*1.修改SynWebReqRes.pas文件,更正TSynWebResponse.GetContent错误, 感谢ivvn (奔腾的心)帮着找虫。
此帖子包含附件:c5soft_20186883815.rar 大小:541.9K
----------------------------------------------
-
作者:
男 c5soft (大道至简) ▲▲▲▲▲ -
普通会员
2018/6/8 9:08:20
41楼: 今天咱们聊聊Web开发前台框架.
总的发展趋势是不是这样的:
1. 前端页面从后端渲染改为前端渲染
2. 多页面应用变单页面应用(SPA)
3. 走MVC/MVVM路线, 页面呈现与业务逻辑分离
4. 前后台通过API通讯,数据交换用JSON

用Delphi的mORMot框架咱们把后端搞定了,前端用什么呢?
前端框架有很多选择,老一代的ExtJs, Dojo, jQuery等等都应该解甲归田了,怕是要在Angular,Vue,React这三位中选择一位?

最近在学React, 这个东西很爽,比以前我自己搞了好久的Sencha ExtJS灵活多了。各位有什么高见?

顺便也看了看Typescript,Woooo,已经3.0了, Anders Hejlsberg真是编译器天才,把个Javascript搞得如此活灵活现,太可惜了,放弃了Native Code,尼玛虚拟机上再怎么搞,也搞不快。
----------------------------------------------
-
作者:
男 synnefo (Syn) ▲▲▲▲△ -
普通会员
2018/6/8 10:21:56
42楼: 赞同,下一个项目就准备使用mORMot + Vue.js
----------------------------------------------
-
作者:
男 ivvn (奔腾的心) ★☆☆☆☆ -
普通会员
2018/6/8 15:45:48
43楼: 我已经在用了
其实我手上有洞主的代码

所以很早就用了

不过感觉c5的代码更简洁
----------------------------------------------
-
作者:
男 ivvn (奔腾的心) ★☆☆☆☆ -
普通会员
2018/6/8 16:00:20
44楼: 我建议开一个群
----------------------------------------------
-
作者:
男 dunken (dunken) ★☆☆☆☆ -
盒子活跃会员
2018/6/9 9:59:12
45楼: 顶,正在学习
----------------------------------------------
-
作者:
男 sxqwhxq (步惊云) ★☆☆☆☆ -
普通会员
2018/6/9 16:13:44
46楼: 希望下一版本,emb能把morMot给封装了。
----------------------------------------------
-
作者:
男 c5soft (大道至简) ▲▲▲▲▲ -
普通会员
2018/6/10 5:10:36
47楼: 今天咱们继续聊Web开发前台框架:Vue与React用谁?我用React。
这两个框架没有谁好与谁不好之分,用谁不用谁是个人口味。
React是清蒸,Vue是红烧。
React是西方语言,就像英文由26个字母组成。Vue是东方语言,就像汉字由300个偏旁部首组成。
React的优势是逻辑简单,用简单的元素构建复杂的项目必然篇幅较长,但是捉虫容易。
Vue的优势是效率更高,三下五除二把项目搞定,但项目中有点头疼脑热不好医。
React靠法制,大家说好都遵守交通规则,红灯亮了,死等,左右无车也不走。
Vue靠人制,谁厉害听谁的。什么红灯绿灯,只要没被摄像头拍到,就不算违章。拍到了也不要紧,老子有关系,可以消。
----------------------------------------------
-
作者:
男 c5soft (大道至简) ▲▲▲▲▲ -
普通会员
2018/6/10 7:34:36
48楼: 用React,你仍然在用原来的HTML,你用Javascript来包装HTML。工程的品控主要取决于YOU。
用Vue,你用的不是原来的HTML了,而是YOUML(尤氏标记语言),你用YOUML来包装Javascript。工程的品控取决于YOU AND YOU。
----------------------------------------------
-
作者:
男 ivvn (奔腾的心) ★☆☆☆☆ -
普通会员
2018/6/10 12:21:45
49楼: 我用JQ的那个ui
----------------------------------------------
-
作者:
男 lanhong (HDA) ★☆☆☆☆ -
普通会员
2018/6/13 15:08:05
50楼: c5soft (大道至简)  有没有react +  mORMot 的小例子啊,发一个入门一下
----------------------------------------------
-
作者:
男 wiseinfo (wisienfo) ★☆☆☆☆ -
普通会员
2018/6/13 17:03:33
51楼: 好贴, 学习了很多姿势

用WebBroker, 与其打磨HTTP.SYS, 
还不如直接编译成DLL+APACHE似乎可以解决一切不爽

DataSnap也可以是WebBroker
RO也有ROWebBroker

INNO打包APACHE+DLL也实在方便
----------------------------------------------
-
作者:
男 lcy98162 (影子) ★☆☆☆☆ -
盒子活跃会员
2018/6/14 8:45:19
52楼: 不考虑跨平台的话 WebBroker + HTTP.SYS(mORMot) 方式还是不错的。 编译成独立EXE或WIN系统服务都可以布署也简单。数据传输使用 FireDAC 内存表速度方法非常不错。本人测试发现主要的效率瓶颈已经不在服务上而是在数据库方面了。
----------------------------------------------
-
作者:
男 bbnn38 (伟大的咸鱼) ★☆☆☆☆ -
普通会员
2018/6/20 3:41:33
53楼: @c5soft (大道至简)
发现个很奇怪的问题,我在windows 10 上面用 delphi 10.2.3 编译 SynBroker 0.9.2.0 版
发现:
如果选择INDY模式,我在局域网内的手机和linux系统都可以正常访问这个网站,如果用MORMOT模式编译的话,只能在windows10本机访问,局域网内的手机和linux系统都访问不了,而且是卡在那了,不像访问不存在的网站一下子就返回错误,

而且我发现如果是INDY模式编译的话你第一次打开系统会问你防火墙是否放行,但MORMOT模式编译出来的就没这个防火墙放行提示,会不会跟这个有关?
----------------------------------------------
-
作者:
男 bbnn38 (伟大的咸鱼) ★☆☆☆☆ -
普通会员
2018/6/20 4:23:29
54楼: 跑来另一个办公室,不同的局域网,换了WINDOWS7专业版系统,用DELPHI10.2.1编译,问题依旧,还是INDY模式编译出来的远程一切正常,MORMOT的http.sys模式下编译出来的程序打开 依旧没有防火墙信息出现,局域网里面的苹果安卓手机都无法访问,只能本地访问

以上测试全部使用管理员权限打开软件了
----------------------------------------------
-
作者:
男 c5soft (大道至简) ▲▲▲▲▲ -
普通会员
2018/6/20 7:59:33
55楼: 把防火墙,360安全卫士/火绒关闭就可以了。
----------------------------------------------
-
作者:
男 vmao (毛小毛) ★☆☆☆☆ -
盒子活跃会员
2018/6/20 8:03:11
55楼: 看得脑袋疼,我们这种只关注于业务逻辑的,是不是直接选择kbmMW就好了?
另外,TClientDataSet真不是什么好东西,数据量大一点内存使用直接爆增。
----------------------------------------------
-
作者:
男 bbnn38 (伟大的咸鱼) ★☆☆☆☆ -
普通会员
2018/6/20 8:28:00
56楼: OK,把所有的防火墙都关了就好了.
----------------------------------------------
-
作者:
男 zhangl (二黑) ★☆☆☆☆ -
盒子活跃会员
2018/6/20 8:34:01
57楼: 我也是win10系统, 先以管理员身份运行一次, 之后就好了
----------------------------------------------
报到
作者:
男 ly_new (kkk) ★☆☆☆☆ -
盒子活跃会员
2018/6/27 15:03:47
58楼: xp下delphi7可以编译但不能运行
----------------------------------------------
-
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2018/6/27 15:05:41
59楼: d7 能编译,说明 D7 自己是正常。不能运行,就 DEBUG 啊。
新建一个 VCL 工程,试试。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 ly_new (kkk) ★☆☆☆☆ -
盒子活跃会员
2018/6/27 17:17:31
60楼: /// classes implementing HTTP/1.1 client and server protocol
// - this unit is a part of the freeware Synopse mORMot framework,
// licensed under a MPL/GPL/LGPL tri-license; version 1.18
unit SynCrtSock;

if Http.Version.MajorVersion<2 then
    raise EHttpApiServer.Create(hSetRequestQueueProperty, ERROR_OLD_WIN_VERSION);

提示指定程序需要更新的windows版本
此帖子包含附件:
PNG 图像
大小:8.6K
----------------------------------------------
-
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2018/6/27 17:26:33
61楼: 原来是 mormot 的一部分。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 feiyanm (feiyanm) ▲▲▲▲▲ -
普通会员
2018/6/28 9:33:43
62楼: 我也瞎说几句吧:
1.下面这段是橙子Demo的一个代码的Uses段,我相信你绝对看过比这个更恐怖的Uses段.
uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, 
  FMX.Types, FMX.Graphics, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.StdCtrls,
  uSkinFireMonkeyControl, uSkinFireMonkeyPanel, uSkinFireMonkeyScrollControl,
  uSkinFireMonkeyListBox, uSkinFireMonkeyItemDesignerPanel, uSkinImageList,
  uSkinFireMonkeyImage, uSkinFireMonkeyLabel,uUIFunction,uDrawCanvas,
  uSkinScrollBarType, uSkinItems, uBaseLog, TalkFrame, uSkinListBoxType,
  uSkinFireMonkeyButton, uSkinFireMonkeyFrameImage,
  uSkinFireMonkeyNotifyNumberIcon, uDrawPicture, uSkinFireMonkeyVirtualList,
  uSkinFireMonkeyRoundImage, uSkinFireMonkeyCustomList;
这个说明的问题也很有意思:软件工程越来越庞大,但却要求越来越容易编写和容易使用.这是必然趋势,如果站在这个角度看问题的话,那么脚本语言的强势发展也是必由之路,不必要强制绑死在NativeCode上.这句话肯定会得罪一堆人!如果站在开发者角度,提供一整套完整的中间件解决方案(IIS,Apache,Ngnix,WebLogic...)不就应该是理所当然的吗?毕竟在网络时代,高可靠/高稳定性的服务端不就应该像空气和水一样正常吗?反过来,如果我们从这个角度出发去看很多的脚本语言,我们会发现很多崭新的世界.
2.曾经看过一个B乎的提问:为什么C/C++不适合做Web服务器?
当时看到时,瞬间有找到知音的感觉:我以为只有Delphier才会有这种吐槽,没想到天下Coder是一家的...
3.曾经我也怀疑过Web前端和后端的能力,但面对扑面而来的大数据和更多的服务器集群,说实话,不要说Delphi有成熟可靠的解决方案,就连是否有人提出过可靠的解决方案都值得商榷.这个话题太长了,从这里出发也能看到很多问题:Delphi的适用范围,为什么没落,将来的方向,存在的困境等等都值得深入思考.
4.面对一种崭新的技术或者一种崭新的语言,拥抱还是固守?生存还是si亡?这也绝对值得我们深入思考.
==========
以上只是我个人的瞎说,希望不要对号入座.如果我们能站在更高的高度来看待技术以及技术的发展脉络,也许能减少很多不必要的痛苦...
----------------------------------------------
Delphi威武!千秋万代,一统江湖!Delphi威武!千秋万代,一统江湖!Delphi威武!千秋万代,一统江湖!Delphi威武!千秋万代,一统江湖!Delphi威武!千秋万代,一统江湖!Delphi威武!千秋万代,一统江湖!Delphi威武!千秋万代,一统江湖!我去WC吐一会儿去!
作者:
男 feiyanm (feiyanm) ▲▲▲▲▲ -
普通会员
2018/6/28 9:44:12
63楼: 再多嘴一句吧,更长远一点,我们能看到AI的强势进入,如果也弄个金字塔型的天梯图:

开发者
开发工具
AI(BigData)
WEB
OS
硬件

问题来了:
1.你觉得作为一个开发者,开发工具应该提供什么功能?
2.如果还希望能够快速开发,你觉得开发工具应该是什么样的?以及开发语言是什么样的?
3.如果从这个角度出发,你觉得想D,C/C++这种语言需要怎样改变?其实这个很难很难且是双刃剑...
4.从上面那个天梯图看的话,我们能看到D这个开发工具直接绕开了Web和AI两个层面,结果应该是大家都看到了.
----------------------------------------------
Delphi威武!千秋万代,一统江湖!Delphi威武!千秋万代,一统江湖!Delphi威武!千秋万代,一统江湖!Delphi威武!千秋万代,一统江湖!Delphi威武!千秋万代,一统江湖!Delphi威武!千秋万代,一统江湖!Delphi威武!千秋万代,一统江湖!我去WC吐一会儿去!
作者:
男 jczxdai (草籽) ▲▲▲▲△ -
普通会员
2018/6/28 10:15:48
64楼: 谢谢 c5soft 大师,无私奉献,根据您的例子再封装了pax脚本,真是爽的一批.
此帖子包含附件:
JPEG 图像
大小:146.5K
----------------------------------------------
草籽天涯
作者:
男 bbnn38 (伟大的咸鱼) ★☆☆☆☆ -
普通会员
2018/6/30 10:49:17
65楼: 例程中的客户端读取货币汇率修改后点击保存变更发送回服务器会在
DataSetProvider1.ApplyUpdates(Delta, -1, nErrorCount);
这一句出错
此帖子包含附件:
PNG 图像
大小:8.4K
----------------------------------------------
-
作者:
男 ysoni (ysoni) ★☆☆☆☆ -
普通会员
2018/7/1 6:57:28
66楼: @jczxdai (草籽),介绍下你的封装?
----------------------------------------------
-
作者:
男 jczxdai (草籽) ▲▲▲▲△ -
普通会员
2018/7/3 10:03:38
67楼: @ysoni (ysoni)
思路:
1.判断TWebModule1.WebModule1WebActionItemDefaultAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);请求
2.请求路径中,请求文件扩展名ExtractFileExt(Request.URL),如果是.pas的文件,调用PaxCompiler执行脚本,将执行脚本输出的字符返回给aResponse.Content
3.如果是非.pas的文件,直接返回文件流 aResponse.ContentStream := TFileStream.Create(ExtractFileDir(ParamStr(0)) + '\WWWROOT\'+Request.URL, fmOpenRead or fmShareDenyNone)
4.我将例子上传,只做了简单是实现,大家一起研究,要安装PaxCompiler.v.4.2+mORMot
5.在c5soft大师的基础上,做了一小点封装,水平有限.....
此帖子包含附件:jczxdai_20187310435.zip 大小:4.22M
----------------------------------------------
草籽天涯
作者:
男 bbnn38 (伟大的咸鱼) ★☆☆☆☆ -
普通会员
2018/7/3 19:28:22
68楼: 请教大家个问题
我如果用Request: TWebRequest取我在网页上传的图片
可以用Request.Files[i].Stream 很方便的取到了图片的内容

但是我想用用RouteMap('POST', '/upload', up);

在这个up函数里我在AEnv: TSynWebEnv 参数
很明显看到上传的图片的内容在
AEnv.Context.InContent

但是用什么快捷的方式取出来呢?这个InContent里面有很多内容 
难道要用字符切割的办法吗?有没有像上面的Files[i].Stream 这样的方便一点的东西用?
----------------------------------------------
-
作者:
男 c5soft (大道至简) ▲▲▲▲▲ -
普通会员
2018/7/3 20:40:24
69楼: @bbnn38 (伟大的咸鱼):
参考一下下列代码:
TWebEnv = class(TSynWebEnv)
  protected
    ...
    FMultiPartFields: TMultiPartDynArray;
    function GetMultiPartFields: TMultiPartDynArray;
    procedure processMultiPartFormData; override;
    ...
  public
    ...
    property MultiPartFields: TMultiPartDynArray read GetMultiPartFields;
  end;


procedure TWebEnv.processMultiPartFormData;
var
  i: Integer;
  cFileName, cName, cValue: string;
  mp: TMultiPart;
begin
  MultiPartFormDataDecode(FContext.InContentType, FContext.InContent, FMultiPartFields);
  for i := Low(FMultiPartFields) to High(FMultiPartFields) do begin
    mp := FMultiPartFields[i];
    cFileName := Server.SaveUpload(mp);
    cName := UTF8ToString(mp.Name);
    if Length(cFileName) > 0 then begin
      cValue := FContentFields.Values[cName];
      if Length(cValue) > 0 then cValue := cValue + ',';
      cValue := cValue + cFileName;
      FContentFields.Values[cName] := cValue;
      FMultiPartFields[i].FileName := StringToUTF8(cFileName);
    end
    else FContentFields.Values[cName] := UTF8ToString(StringReplaceAll(mp.Content, #13#10, '\n'));
  end;
end;
----------------------------------------------
-
作者:
男 bbnn38 (伟大的咸鱼) ★☆☆☆☆ -
普通会员
2018/7/3 23:05:29
70楼: @c5soft (大道至简) 啊,刚才没上BBS  所以没看到你发的,浪费了几个小时在TSynWebEnv里自个写了上传文件的解析了,参照了Web.ReqMulti里面的方法,非常感谢你的回复!
----------------------------------------------
-
作者:
男 kuei (kuei) ★☆☆☆☆ -
盒子活跃会员
2018/7/4 23:22:40
71楼: 翻旧资料,这个VCL好像是相似功能,没试过,提供参考吧!

Delphi窑洞有相似文章

使用delphi 开发 web(二)动态脚本的实现

不过是用paxCompiler,这个是用paxScript的,应该比他更久远。

TPaxWebScripter and TPaxPageProducer components for Delphi 7. 
----------
Version: 1.0.
Copyright (c) 2004 Any Key Software Solutions
Author: Don Wibier 
E-Mail: don@anykey.nl
此帖子包含附件:kuei_201874232240.zip 大小:31.1K
----------------------------------------------
-
作者:
男 biznow (biznow) ★☆☆☆☆ -
盒子活跃会员
2018/7/5 15:36:25
72楼: @jczxdai 用你编译的exe和我自己编译的exe做pas脚本压力测试时都会出同样的问题
此帖子包含附件:
PNG 图像
大小:20.2K
----------------------------------------------
-
作者:
男 jczxdai (草籽) ▲▲▲▲△ -
普通会员
2018/7/6 11:56:45
73楼: @biznow (biznow) 肯定会出问题啊,我那个例子,我只写了实现思路,还没有认真完善呢,最起码执行脚本应该是 :不同的session之间,使用不同的线程吧,之前的例子,所有访问者都是同一个对象来执行脚本,并且echo输出使用了一个变量,肯定要出问题的;
我们在继续深入的丰富一下它,呵呵
----------------------------------------------
草籽天涯
作者:
男 bestfw (bestfw) ▲▲▲▲▲ -
普通会员
2018/7/7 1:58:50
74楼: 看大家的讨论,我有些问题想说说,楼主是个技术高人,比我厉害的多,但我不太明白楼主为啥要改造这个webbroker和datasnap的底层通讯。mormot应该是一个支持websocket的库吧。这个东西应该c/s程序用的吧,不是用来提供web服务的吧,用它来和webbroker做web服务器没有意义吧,可以做成dll直接交给iis或者apach之类的web服务器啊。至于datasnap是用来快速开发c/s应用程序的,用的是indy的套件,这个东西本身不存在你们讨论的高并发问题啊,什么样的c/s系统会并发上千的?我也好奇楼主的项目是干啥的,怎么会有这么高的并发⊙﹏⊙,而开发b/s的web应用我觉得还是楼上有个朋友说的,各种脚本语言框架似乎更合适,至少不用考虑这些什么高并发的问题都交给大型web服务器就可以了吧。除非想要做一个更好的web服务器。datasnap提供了restfull服务器以后,可以跨语言开发客户端了,不再局限于delphi了,但是客户端应该是客户端程序而不是web吧。估计它提供的http json返回,让很多人产生了误解,想用它开发web服务器。要知道datasnap的c/s架构程序和web的b/s架构程序是两条路,他们都在奔向对方,导致他们越来越像,也让大家有些迷糊了,其实这两条路径的应用场景是不一样的,我感觉没有必要去混用他们,delphi就不适合开发web这个不承认也不行啊。而我们delphier留恋的就是这个ide和pascal的语法,反而我看论坛上有人说tms出了个控件组直接可以生成html5 css3 js的纯web页面,这比intraweb那种封闭式结合两条路的方式要靠谱的多,也可能是现在的html5更厉害了,有了比如websoket的新协议,我觉得这个似乎就对路了。delphier只能做c/s程序的问题估计会被这种方式拯救,应该要感谢html5让我们又看到delphi继续发展的希望了。
----------------------------------------------
-
作者:
男 bestfw (bestfw) ▲▲▲▲▲ -
普通会员
2018/7/7 11:34:19
75楼: datasnap只适合中小型c/s系统,我觉得楼主大神要是有时间的话不如把mormot封装起来做成组件包,让他更加易用化。我这种低级别程序员用起来会容易的多。这本身也是delphi的思想,快速开发。😂如果mormot真的这么好,不知道会不会被delphi官方收编做成组件包。
----------------------------------------------
-
作者:
男 a200332 (0) ★☆☆☆☆ -
普通会员
2018/7/7 21:45:35
76楼: 应该可以       morm  很好用
----------------------------------------------
-
作者:
男 ycxxlk (小李) ★☆☆☆☆ -
普通会员
2018/9/6 0:42:59
77楼: 感谢楼主的分享,正在试用,不能能否指点一下,我想用SynBroker实现在网页上对服务器数据库的增删改查功能,不知道如何做,还请指点一下,万分感谢!
----------------------------------------------
-
作者:
男 joman (joman) ▲▲▲▲▲ -
普通会员
2018/11/18 10:24:22
78楼: 非常感谢c5soft 提供的代码,
以前开发的bs框架使用了http.sys 后性能明显提升。
有需要的朋友可以去这下载。
https://gitee.com/pearroom/DelphiWebMVC
测试地址 http://47.98.102.37:8001
admin
admin
大家可以测测看
----------------------------------------------
DelphiWeb开发方案(开源):https://gitee.com/pearroom/DelphiWebMVC
作者:
男 moom (小新啊) ▲▲▲△△ -
普通会员
2018/11/19 17:54:52
79楼: D。。。。。。。。
----------------------------------------------
谢谢各位大大
作者:
男 mike1234567890 (Mike) ★☆☆☆☆ -
普通会员
2018/11/22 22:49:51
80楼: 这个要保留太好用了
----------------------------------------------
-
作者:
男 fxb0115 (青石) ★☆☆☆☆ -
盒子活跃会员
2018/11/26 21:53:27
81楼: 感谢c5soft分享!
----------------------------------------------
-
作者:
男 jczxdai (草籽) ▲▲▲▲△ -
普通会员
2019/1/24 17:34:18
82楼: 使用http sys,防火墙放行 对应的端口即可,不用去放行程序,放行程序不生效。
----------------------------------------------
草籽天涯
作者:
男 laimama_1 (苞谷) ★☆☆☆☆ -
盒子活跃会员
2019/1/30 22:16:35
83楼: 我在试验的过程中,出现了65楼相同的问题,请问是怎么解决的?
----------------------------------------------
-
作者:
男 denkun (dk) ★☆☆☆☆ -
普通会员
2019/4/11 17:17:07
84楼:  例子 用Delphi 10 Seattle 编译后 客户端报错
----------------------------------------------
-
作者:
男 gaoyong_gy (gaoyong_gy) ★☆☆☆☆ -
盒子活跃会员
2019/4/11 23:28:42
85楼: https://item.taobao.com/item.htm?spm=2013.1.w4023-6980063914.7.103377fa7pgbLc&id=578557770919
----------------------------------------------
Delphi 的移动程序开发,是您不可再错失的机遇:http://blog.163.com/you888@188/blog/static/6723961920169319529515/
作者:
男 gaoyong_gy (gaoyong_gy) ★☆☆☆☆ -
盒子活跃会员
2019/4/11 23:29:37
86楼: 其实,diocp比httpsys更快。
----------------------------------------------
Delphi 的移动程序开发,是您不可再错失的机遇:http://blog.163.com/you888@188/blog/static/6723961920169319529515/
作者:
男 feiyanm (feiyanm) ▲▲▲▲▲ -
普通会员
2019/4/12 8:31:14
87楼: 删除吧,免得吵架。。。
----------------------------------------------
Delphi威武!千秋万代,一统江湖!Delphi威武!千秋万代,一统江湖!Delphi威武!千秋万代,一统江湖!Delphi威武!千秋万代,一统江湖!Delphi威武!千秋万代,一统江湖!Delphi威武!千秋万代,一统江湖!Delphi威武!千秋万代,一统江湖!我去WC吐一会儿去!
作者:
男 nihao500s (nihao100s) ▲▲△△△ -
普通会员
2019/5/22 15:59:18
88楼: 北京私家侦探
上海搬家公司
私家侦探
----------------------------------------------
-
作者:
男 vga (vga) ★☆☆☆☆ -
盒子活跃会员
2019/5/31 17:12:18
89楼: 我把服务程序部署在 win10 上测试 一切正常,但部署在 win2008服务其上
客户端 就会 报错,这个问题 不太就好说清楚,稍后 把程序贴出来,不知大家是否遇到过?
此帖子包含附件:
JPEG 图像
大小:22.3K
----------------------------------------------
-
作者:
男 vga (vga) ★☆☆☆☆ -
盒子活跃会员
2019/5/31 17:15:23
90楼: 这是客户端的测试代码:
procedure TFormMain.Button2Click(Sender: TObject);
var
  sql, rlt: string;
  jDataSet: TJSONArray;
  jRecord: TJSONObject;
begin
  rio.URL := edtUrl.Text;

  sql := 'SELECT * from zd_order o WHERE o.ID_Order=999999';
  rlt := (rio as itest).OpenQuery(sql);
  jDataSet := TJSONObject.Create.ParseJSONValue(rlt, True) as TJSONArray;
  jRecord := jDataSet.Get(0) as TJSONObject;
  showmessage(jRecord.GetValue('ID_Order').Value);
end;
----------------------------------------------
-
作者:
男 vga (vga) ★☆☆☆☆ -
盒子活跃会员
2019/5/31 17:17:33
91楼: 这是服务端的代码
function TTest.OpenQuery(sql: string): string;
// 查询结果数据集 以 json 文本返回
var
  dst: TDataSet;
begin
  dst := _CreateDataSetBySQL(sql);
  Result := _DataSetToJson(dst);
  _ReleaseDataSet(dst);
end;

function _DataSetToJson(ADataset: TDataSet): string;
// [{"CityId":"18","CityName":"西安"},{"CityId":"53","CityName":"广州"}]
var
  LRecord: string;
  LField: TField;
  i: Integer;
begin
  Result := '';
  if (not ADataset.Active) or (ADataset.IsEmpty) then
    Exit;
  Result := '[';
  ADataset.DisableControls;
  ADataset.First;
  while not ADataset.Eof do
  begin
    for i := 0 to ADataset.FieldCount - 1 do
    begin
      LField := ADataset.Fields[i];
      if LRecord = '' then
        LRecord := '{"' + LField.FieldName + '":"' + LField.Text + '"'
      else
        LRecord := LRecord + ',"' + LField.FieldName + '":"' + LField.Text + '"';
      if i = ADataset.FieldCount - 1 then
      begin
        LRecord := LRecord + '}';
        if Result = '[' then
          Result := Result + LRecord
        else
          Result := Result + ',' + LRecord;
        LRecord := '';
      end;
    end;
    ADataset.Next;
  end;
  ADataset.EnableControls;
  Result := Result + ']';
end;


function _CreateDataSetBySQL(sql: string): TDataSet;
// 此函数与_OpenQuery 完全相同,旨在提醒用户释放资源
var
  ZReadOnlyQuery1: TZReadOnlyQuery;
begin
  ZReadOnlyQuery1 := TZReadOnlyQuery.Create(nil);
  ZReadOnlyQuery1.SQL.Text := sql;
  ZReadOnlyQuery1.Connection := ConnPool.GetConn;
  try
    ZReadOnlyQuery1.Open;
    result := ZReadOnlyQuery1;
  except
    ZReadOnlyQuery1.Free;
    result := nil;
  end;
end;
----------------------------------------------
-
作者:
男 kwer (★★★★★) ★☆☆☆☆ -
普通会员
2020/4/1 16:54:58
92楼: 感谢c5soft热心心肠提供高质量代码,建议发到github
----------------------------------------------
==========-==========-==========-==========-==========
     多隆, 给我备一匹最快的马, 我有事要走先~~~
==========-==========-==========-==========-==========
作者:
男 vga (vga) ★☆☆☆☆ -
盒子活跃会员
2020/10/22 14:08:27
93楼: 非常 感谢c5soft 的无私奉献!!!

测试中遇到一个小问题:当三个字段的值 输入为: “姓名”时,提交,再返回,这三个字段的 值会 丢失 “名”,
此帖子包含附件:
PNG 图像
大小:30.9K
----------------------------------------------
-
作者:
男 c5soft (大道至简) ▲▲▲▲▲ -
普通会员
2020/10/23 11:05:06
94楼: 两年前的帖子还有人关注,不妨说两句:
1.Delphi基于http.sys做Web这条路是走得通的,用于生产环境的系统已运行多年。开发中会有一些小坑,需要有调试http程序的功底,需要用到一些工具,比如HTTPAnalyzer等等;
2.这套方案支持并发没有问题,10K级吧,速度也是很快的;
3.这套方案的稳健性会也是比较可靠的,一年可能会有那么一两次需要重启的时候。
尽管如此,还是有更好的工具拿来写Web, 当下如果让我推荐,我倾向于用Rust语言,选warp架构。
----------------------------------------------
-
作者:
男 vga (vga) ★☆☆☆☆ -
盒子活跃会员
2020/10/23 13:28:19
95楼: 多谢  c5soft (大道至简) 大神的 解答 与 指导!
的确,时间久了点,但这正是说明 这样一个开创先河的作品案例影响之大!是大神的这个作品的确为我们带来了许多种可能,性能也是非常优秀!!!

关于 rust 语言也希望 大神多发表一些文章和 案例。
----------------------------------------------
-
作者:
男 pcplayer (pcplayer) ★☆☆☆☆ -
普通会员
2020/10/23 16:22:24
96楼: 多层的程序,不外乎两种技术需求:
1. 传递数据库;
2. 把一些函数操作,通过网络通讯来传递。也就是远程调用。

在此基础上,服务器端的通讯基础,是采用纯 TCP Server 还是采用某个 WEB Server,那么,这个是选择基础通讯的效率、稳定性的问题。

当然,http.sys 的效率肯定高。选择它没错。

在 http 的基础上,在 Delphi 底下,比较好的远程函数调用框架是 SOAP 框架。想办法移植 SOAP 上去应该更好玩。

至于数据库,当然在以前就是 ClientDataSet 那套。现在应该是可以采用 FireDAC 那套了。
----------------------------------------------
-
作者:
男 studyd (studyd) ▲▲▲△△ -
普通会员
2020/10/24 7:49:04
97楼: 感谢 c5soft (大道至简),让Delphi走出了另一条路,非常好
----------------------------------------------
-
作者:
男 siaosa (siaosa) ★☆☆☆☆ -
盒子活跃会员
2020/10/26 8:23:08
98楼: http.sys支持Linux不?
----------------------------------------------
-
作者:
男 pp0123 (pp0123) ★☆☆☆☆ -
普通会员
2020/10/26 9:58:18
99楼: HTTP.SYS是启动被称为HTTP堆栈,或超文本传输协议栈的应用程序的Windows驱动程序文件。这是由于Windows操作系统的一部分,这意味着该文件被与OS软件一起安装。这是你的Windows网络子系统,它提供了在漏斗的HTTP的Web浏览器请求援助;或者换句话说,该文件是用于Internet信息服务器的​​支持。该文件有使用缺省值C命令的路径:\ WINDOWS \ SYSTEM 32 \ DRIVERS \ HTTP.SYS。常见的文件大小为262,400字节,262,784字节之间。由开发人员创建的终点通常的HTTP与文件HTTP.SYS注册,不再需要通过IIS。该文件被认为是一种无害的文件,因为它是由微软验证,并与Windows操作系统软件安装。该文件还没有被连接到任何恶意软件。虽然该文件可以从运行作为Windows服务被禁用,不建议这样做,特别是如果你连接到互联网上相当定期。
----------------------------------------------
-
作者:
男 feiyanm (feiyanm) ▲▲▲▲▲ -
普通会员
2020/10/26 10:59:04
100楼: Pascal脚本弄的网站:http://www.moonserver.cn/mhs/single-post.pp?id=68&catalog=1
网站是一个非常古老的版本,1c1g1m的服务器也顺利运行16个月了,没有重启过。
总之一句话:http.sys是非常靠谱的。
----------------------------------------------
Delphi威武!千秋万代,一统江湖!Delphi威武!千秋万代,一统江湖!Delphi威武!千秋万代,一统江湖!Delphi威武!千秋万代,一统江湖!Delphi威武!千秋万代,一统江湖!Delphi威武!千秋万代,一统江湖!Delphi威武!千秋万代,一统江湖!我去WC吐一会儿去!
作者:
男 foryour (sean) ★☆☆☆☆ -
普通会员
2020/10/27 10:15:38
101楼: mark
----------------------------------------------
-
作者:
男 baifafa (白花花) ★☆☆☆☆ -
盒子活跃会员
2021/1/16 22:25:20
102楼: 学习中,谢谢c5大神
----------------------------------------------
没有比没有更没有
作者:
男 baifafa (白花花) ★☆☆☆☆ -
盒子活跃会员
2021/1/18 16:34:29
103楼: 在win7 64位下ab 10万个压测,进程中内存3M多点没什么增加,说明内存没什么泄漏,程序很稳定。

楼主,强强强
----------------------------------------------
没有比没有更没有
作者:
男 baifafa (白花花) ★☆☆☆☆ -
盒子活跃会员
2021/1/18 16:41:39
104楼: ab -n 100000  -c 10000 http://127.0.0.1:8080/
此帖子包含附件:
PNG 图像
大小:56.5K
----------------------------------------------
没有比没有更没有
作者:
男 baifafa (白花花) ★☆☆☆☆ -
盒子活跃会员
2021/1/26 15:34:55
105楼: 95%的人要1分钟才能看到结果,有几个人能接受呢
----------------------------------------------
没有比没有更没有
作者:
男 baifafa (白花花) ★☆☆☆☆ -
盒子活跃会员
2021/1/27 15:06:44
106楼: kao,看错了,是3.5s
----------------------------------------------
没有比没有更没有
作者:
男 hsan (hsan) ★☆☆☆☆ -
普通会员
2021/5/21 15:28:44
107楼: DataClient.exe  用delphi 10.4.2编译,获取数据正常 保存出错,提示 missing connection or connetionstring  
有哪位知道原因吗
----------------------------------------------
-
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行257.8125毫秒 RSS