转载: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. 年前辞职-WCF入门学习(5)

    前言 第五集比较简单,视频也只有7分多钟,但是用处还是挺大的.下面我会介绍. 本来想第六集一起介绍的,后来发现第六集内容比较多,有半个多小时,就不一起了.网站规定6小时内只能发布一篇文章到首页,,那我 ...

  2. org.hibernate.PropertyValueException: not-null property references a null or transient value:

    org.hibernate.PropertyValueException: not-null property references a null or transient value: com.bj ...

  3. C# 全角符号转半角

    public static string SBCCaseToNumberic(string SBCCase) { char[] c = SBCCase.ToCharArray(); ; i < ...

  4. 牛客网上的剑指offer题目

    题目:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 题目:请实现一个函数,将一 ...

  5. Cocos2d-X3.0 刨根问底(九)----- 场景切换(TransitionScene)源码分析

    上一章我们分析了Scene与Layer相关类的源码,对Cocos2d-x的场景有了初步了解,这章我们来分析一下场景变换TransitionScene源码. 直接看TransitionScene的定义 ...

  6. linux中为什么已经是root用户仍不能执行程序

    .sh文件 ,获取root权限,提示Permission Denied. 这是因为文件本身没有可执行特性. chmod +x a.sh chmod 755 a.sh

  7. JAVA中的数组是对象吗?

    public class Main{ public static void main(String[] args) { int a[]={1,9}; //Object obj=new int[10]; ...

  8. POJ3628 Bookshelf 2(01背包+dfs)

    Bookshelf 2 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8745   Accepted: 3974 Descr ...

  9. poj1631Bridging signals(最长单调递增子序列 nlgn)

    Bridging signals Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 12251   Accepted: 6687 ...

  10. memcached安装和php-memcached扩展安装.update.2014-08-15

    服务器端主要是安装memcache服务器端,目前的最新版本是 memcached-1.3.0 .下载官网:http://www.danga.com另外,Memcache用到了libevent这个库用于 ...