Tag: Delphi .net WebService
最近公司有个系统升级,老系统为delphi所编写;老系统为传统的C/S两层结构,有一个瓶颈就是我们的客户端经常需要从数据库刷新数据
,而且这些数据都是一样的,这极大地影响了系统效率,在系统升级时我们考虑使用WebService解决这一瓶颈;初步想法是需要刷新数据时由
WebService中间层去数据库提取数据,所有的客户端都到中间层拿刷新后的数据,这样就避免了所有的客户端都直接去操作数据库提取同样的
数据。但是用什么平台实现WebService中间层呢?根据公司的技术特点,那么我们初步定为考虑.net和delphi自己做中间层。
用.net作为中间层实现,优势很明显:
1.微软已经把WebService框架搭建好,开发非常简单;
2.我们的服务器为微软平台,使用微软的.net技术应当能够提供很好的效率;
3..net平台提供了现成的全局Session对象,很容易实现我们的需求。
劣势为:
1. 系统采用两套开发平台,接口不统一;比如说.net的数据集DataSet在delphi里怎么用?
2. 两套开发平台增加程序员学习难度和维护难度;
使用delphi作为中间层实现,我们预想好处为:
1. 中间层和客户端都为delphi实现,提供较好的兼容性,可能可以直接传递数据集;
2. 统一的开发平台,易于学习和维护;
劣势为:
1. 我们使用的Delphi版本为6.0,显然它不是作为分布式开发的主流平台;
2. 如何控制全局数据集估计没有.net方便;
3. 效率不可预见;
我查阅了很多文章,有如下结论:
1. Delphi作为中间层实现的话,除了能够传递简单类型以外;负载类型只能支持继承自TRemoteTable的子孙类,以及这些子孙类组成的动态
数组;这样我所预想的直接传递数据集的想法落空;只能在中间层得到数据集后,变为动态数组传递到客户端,客户端解析后还原为数据集,
效率太低;
2. .net平台DataSet可以化为xml数据流传递为delphi客户端,delphi客户端可以根据事先定义好的解析文件,将此xml数据流装载到
TClientDataSet中;
就这两点就足以使我选择了.net作为中间层实现;
其中的技术关键点就是中间层的DataSet和Delphi的ClientDataSet的转换,下面给出具体实现方法:
.net端的示例代码如下:
DataSet ds = SqlHelper.ExecuteDataset(conStr,CommandType.Text,sqlText);//得到DataSet
System.Text.StringBuilder strbuilder=new System.Text.StringBuilder();
System.IO.StringWriter writer=new System.IO.StringWriter(strbuilder);
ds.WriteXml(writer,System.Data.XmlWriteMode.IgnoreSchema);//将DataSet转换为xml数据流,忽略一些dataset特有的动作结构等
return strbuilder.ToString();
客户端收到的数据流入下所示:
<车辆编码>00001
<实际标识>adah
<工作状态>8
<所属分站编码>001
<插入时间>2005-08-23T10:15:28.6170000+08:00
<车辆编码>00002
<实际标识>b
<工作状态>7
<所属分站编码>002
<插入时间>2005-08-23T11:11:56.7570000+08:00
<车辆编码>00003
<实际标识>c
<工作状态>64
<所属分站编码>003
<插入时间>2005-08-23T11:15:52.3070000+08:00
注意,我们需要给这个xml文件流添加第一行。
将这个xml文件流保存到文件data.xml中;用自带的工具XmlMapper打开data.xml,生成transfromation结构,保存到Todp.xtr文件中;
Delphi端演示代码
var
xmlStr: string;
st: TSTringStream;
XMLDoc:IXMLDocument;
begin
xmlStr:= GetService1Soap.GetAmbulance;
xmlStr:= '' + #10 + xmlStr;
st:= TStringStream.Create(xmlStr);
ClientDataset1.Active := FALSE;
//SOAPResponse.Position := 0;
XMLDoc := NewXMLDocument;
XMLDoc.Encoding := 'GB2312';
//SOAPResponse.Position := 0;
XMLDoc.LoadFromStream(st);
XMLTransformProvider1.TransformRead.SourceXmlDocument := XMLDoc.GetDOMDocument;
ClientDataset1.Active := TRUE;
其中XMLTransformProvider1的TransformRead的TransformationFile属性选择我们生成的Todp.xtr,ClientDataSet1的Providor属性选择
XMLTransformProvider1;这样就将数据倒入道ClientDataSet中。