转载:http://blogs.embarcadero.com/jimtierney/2009/04/06/31461/

DataSnap Server Method Stream Parameters

This is a continuation of my posts on DataSnap server method parameters and return types.  This post is about  TStream and TDBXStreamValue.    The sample client and server projects that go with this post can be downloaded here: http://cc.embarcadero.com/item/26854

See my earlier posts on “Basic” and “Basic DBXValue” types.   I’ve yet to post about TDBXConnection, TDBXConnectionValue, TDBXReader, TParams, and TDataSet.  However, TDataSet is demonstrated in the sample projects.

Basic Basic DBXValue Collection Connection
  • AnsiString
  • Boolean
  • Currency
  • TDateTime
  • TDBXDate
  • TDBXTime
  • Double
  • Int64
  • Integer
  • LongInt
  • OleVariant
  • Single
  • SmallInt
  • WideString
  • TDBXAnsiStringValue
  • TDBXAnsiCharsValue
  • TDBXBcdValue
  • TDBXBooleanValue
  • TDBXDateValue
  • TDBXDoubleValue
  • TDBXInt16Value
  • TDBXInt32Value
  • TDBXInt64Value
  • TDBXSingleValue
  • TDBXStringValue
  • TDBXTimeStampValue
  • TDBXTimeValue
  • TDBXWideCharsValue
  • TDBXWideStringValue
  • TDBXReader
  • TDataSet
  • TParams
  • TStream
Collection DBXValue
  • TDBXReaderValue
  • TDBXStreamValue
  • TDBXConnection
Connection DBXValue
  • TDBXConnectionValue

The following table summarizes differences between TStream and TDBXStreamValue types:

  Supports null values Declaration Accessing Values Proxy generator
Default parameter direction Other parameter directions function result type Get Set
TStream No

in

in/out: usevar keyword out: use outkeyword

Yes

lhs := AParameter AParameter := rhs

Yes

TDBXStreamValue

Yes

in/out

None

No

AParameter.IsNull lhs:=AParameter.GetStream(InstanceOwner) AParameter.SetNull AParameter.SetStream(rhs, InstanceOwner)

No

Supports null values

The TDBXStreamValue type has an IsNull property and a SetNull method.   Use this type instead of TStream a parameter value can be null/nil, in some cases.

Declaration

The var and out keywords can’t be used to specify the parameter direction of a TDBXStreamValue parameter.  The direction is always in/out. A TDBXStreamValue type can’t be used as a function result.

Proxy Generator

The RAD Studio 2007 client proxy generator does not work properly for server methods with TDBXStreamValue parameters. So you will need to hand code the client code or correct the generated proxy. The sample client has hand corrected proxy methods that look like this.

function TTestStreamValueClient.Echo(var I: TStream): TStream;
begin
if FEchoCommand = nil then
begin
FEchoCommand := FDBXConnection.CreateCommand;
FEchoCommand.CommandType := TDBXCommandTypes.DSServerMethod;
FEchoCommand.Text := 'TTestStreamValue.Echo';
FEchoCommand.Prepare;
end;
if I = nil then
FEchoCommand.Parameters[0].Value.SetNull
else
FEchoCommand.Parameters[0].Value.SetStream(I, FInstanceOwner);
FEchoCommand.ExecuteUpdate;
if FEchoCommand.Parameters[0].Value.IsNull then
I := nil
else
I := FEchoCommand.Parameters[0].Value.GetStream(FInstanceOwner);
Result := FEchoCommand.Parameters[1].Value.GetStream(FInstanceOwner);
end;

This client method works with a server method declared as follows:

function Echo(I: TDBXStreamValue): TStream;

Calling a server method with a TDBXStreamValue parameter is the same as calling a server method with an TStream parameter, except that you can use SetNull and IsNull methods to work with null values.

For example, compare the following server method declaration and client method implementation to the previous example:

function Echo(I: TStream): TStream; 
function TTestStreamClient.Echo(I: TStream): TStream;
begin
if FEchoCommand = nil then
begin
FEchoCommand := FDBXConnection.CreateCommand;
FEchoCommand.CommandType := TDBXCommandTypes.DSServerMethod;
FEchoCommand.Text := 'TTestStream.Echo';
FEchoCommand.Prepare;
end;
FEchoCommand.Parameters[0].Value.SetStream(I, FInstanceOwner);
FEchoCommand.ExecuteUpdate;
Result := FEchoCommand.Parameters[1].Value.GetStream(FInstanceOwner);
end;

Accessing Values

The GetStream and SetStream methods have an InstanceOwner parameter.  Passing True indicates that DBX owns the stream and will free it.  Passing False indicates that the caller owns the stream.  To control how the generated proxy classes call SetStream and GetStream, there is an AInstanceOwner parameter on the proxy class constructor:

constructor TTestStreamClient.Create(ADBXConnection: TDBXConnection; AInstanceOwner: Boolean);

The other constructor is equivalent to passing AInstanceOwner as True.

constructor TTestStreamClient.Create(ADBXConnection: TDBXConnection);

Sample Client And Server Applications

The sample server has a few simple server methods for passing values (including null).

  {$METHODINFO ON}
TTestCollection = class(TComponent)
strict protected
procedure LogMessage(const AMessage: string);
public
// Server method to get the parameter type names
procedure GetTypeNames(I: T; ADeclaredName, AActualName: TDBXStringValue);
end;
{$METHODINFO OFF} TTestStream = class(TTestCollection)
public
function Echo(I: TStream): TStream;
procedure Copy(I: TStream; out J: TStream);
procedure Swap(var I: TStream; var J: TStream);
end; TTestStreamValue = class(TTestCollection)
public
function Echo(I: TDBXStreamValue): TStream;
procedure Copy(I: TDBXStreamValue; J: TDBXStreamValue);
procedure Swap(I: TDBXStreamValue; J: TDBXStreamValue);
function IsNull(I: TDBXStreamValue): Boolean;
procedure SetNull(I: TDBXStreamValue);
end;

The sample client tests the server methods by calling them with sample values and verifying the results (e.g; comparing streams). TMemoryStream is used to pass short streams and TFileStream to pass long streams.  Here is a screen shot of the running server and client:

The following table shows the parameter types and return types demonstrated in the sample client and server:

Type Direction
(default) var out Result
TDBXStreamValue X (in/out)      
TStream X (in) X X X

Stream Usage

Check  “Log Stream Usage” to show TStream sizes, type names, creates, destroys, and reads.  The results from 4 different test cases are displayed after “Call Server Methods” is clicked.

The screen shot below shows the result from a test case with longer streams.  I’ve added highlighting to illustrate these points:

  1. When the server reads a longer stream passed from the client, round trips are made to the client.  This makes it possible to send very large streams to the server without consuming lots of memory.
  2. When the client reads a longer stream passed from the server, round trips are made to the server.  This makes it possible to return very large streams to the client without consuming lots of memory.
  3. The TStream objects that represent longer client and server streams have a Size of –1, meaning the size is unknown.  Rely on the return value of TStream.Read to detect the end of the stream.  Also note that some DBX streams such as TDBXStreamReaderStream do not fully support Seek.

That’s all for now.

附件:( http://cc.embarcadero.com/item/26854 链接的文件)

关于 datasnap Stream的英文博客能容的更多相关文章

  1. 30大最有影响力的Web设计与开发英文博客

    1stwebdesigner的创始人Dainis Graveris挑选出30个高质量和具有影响力的Web设计与前端技术博客,其中很多我们都耳熟能详.但这么完整的列表,还是值得收藏的.另外,你大概不会了 ...

  2. 值得关注的 10 个 Python 英文博客

    英文原文:http://pythontips.com/2013/07/31/10-python-blogs-worth-following/ 中文翻译参考: http://python.jobbole ...

  3. 本文可能是国内第一篇介绍C/4HANA Foundation的中文博客

    SAP C/4HANA从去年发布已经过去了一年多的时间,C/4HANA的从业者,对于这五朵云里包含的产品集,想必都有了一些了解. Jerry注意到,SAP C/4HANA Foundation这个概念 ...

  4. 1、了解计算机与操作系统发展阶段 2、选择一个具体的操作系统,结合计算机与操作系统的发展阶段,详细了解其渊源、发展过程、趋势,整理成简洁美观的图文博客发布。 Windows Mac os x Unix Linux Android 等。

    1.了解计算机与操作系统发展阶段 操作系统并不是与计算机硬件一起诞生的,它是在人们使用计算机的过程中,为了满足两大需求:提高资源利用率.增强计算机系统性能,伴随着计算机技术本身及其应用的日益发展,而逐 ...

  5. 【相关网站 - 02】- Java 好文博客

    一.源码分析博客 还有这种操作?浅析为什么要看源码 你觉得什么才是 Java 的基础知识? 1. JDK 2. Mybatis 3. Spring 4. Sring Boot 5. Spring Cl ...

  6. CasperJS API中文博客链接

    http://www.cnblogs.com/reach296/tag/Casperjs/

  7. Windows Azure中文博客 Windows Azure入门教学系列 (一): 创建第一个WebRole程序

    http://blogs.msdn.com/b/azchina/ 本文转自:http://blogs.msdn.com/b/azchina/archive/2010/02/09/windows-azu ...

  8. 七步,搭建基于Windows平台完美Jekyll博客环境

    最近,基于Jekyll新搭建了自己英文博客.整个过程搜索了不少资料,也尝试和过滤了不少工具和插件,最后的效果还是不错的.这里总结一下主要的七个步骤,感兴趣的朋友可以参考一下: 第一步,安装Ruby开发 ...

  9. 对写博客的n种思考

    喜欢才能坚持 开始写博客的原因非常功利,功利到不好意思说. 反正你们也懂的,就那么几种. 问题是,如果心态一直这么功利,而写博客的前期回报几乎为零,情绪会变得沮丧,不知如何继续. 不过后来想想,其实做 ...

随机推荐

  1. JAVA中的NIO(二)

    一.内存文件映射 内存文件映射允许我们创建和修改那些因为太大而不能放入内存中的文件.有了内存文件映射,我们就可以假定整个文件都在内存中,而且可以完全把文件当作数组来访问. package com.dy ...

  2. 《TCP/IP详解卷1:协议》第3章 IP:网际协议(1)-读书笔记

    章节回顾: <TCP/IP详解卷1:协议>第1章 概述-读书笔记 <TCP/IP详解卷1:协议>第2章 链路层-读书笔记 <TCP/IP详解卷1:协议>第3章 IP ...

  3. 工作的思考十五:升职前需要做的准备(TeamLeader)

    当一个人在公司的工作年限以及经验的积累到达一个程度的时候,升职其实是件高兴的事,但面临角色的转变需要提前做些准备的. 其实如果你对你的职业规划很清楚的话,那么你就应该在升职之前就会开始进行角色的转换. ...

  4. AngularJS开发指南6:AngularJS表单详解

    表单控件(input, select, textarea )是用来获取用户输入的.表单则是一组有联系的表单控件的集合. 用户能通过表单和表单控件提供验证的服务,知道自己的输入是否合法.这样能让用户交互 ...

  5. 2016 版 Laravel 系列入门教程(二)【最适合中国人的 Laravel 教程】

    本教程示例代码见: https://github.com/johnlui/Learn-Laravel-5 在任何地方卡住,最快的办法就是去看示例代码. 本篇文章中,我将跟宝宝们一起学习 Laravel ...

  6. MyEclipse内存不足问题

    1.修改eclipse.ini 在Myeclipse安装目录下G:\MyEclipse8.5\Genuitec\MyEclipse 8.5有一个myeclipse.ini配置文件,设置如下: -vma ...

  7. iOS开发中的错误整理,重写的构造函数中,没有通过self调用

  8. JS模式:又一个简单的工厂模式

    <!DOCTYPE html> <html> <head> <title></title> </head> <body&g ...

  9. 【CodeForces 618C】Constellation

    题 Cat Noku has obtained a map of the night sky. On this map, he found a constellation with n stars n ...

  10. 【BZOJ-2588】Count on a tree 主席树 + 倍增

    2588: Spoj 10628. Count on a tree Time Limit: 12 Sec  Memory Limit: 128 MBSubmit: 3749  Solved: 873[ ...