zoukankan      html  css  js  c++  java
  • 关于 datasnap Stream的英文博客能容

    转载: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.

    BasicBasic DBXValueCollectionConnection
    • 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 valuesDeclarationAccessing ValuesProxy generator
    Default parameter directionOther parameter directionsfunction result typeGetSet
    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:

    TypeDirection
    (default)varoutResult
    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 链接的文件)

  • 相关阅读:
    TypeScript reflect-metadata 结合方法装饰器实现的一个自定义语法检查的例子
    使用 TypeScript 自定义装饰器给类的方法增添监听器 Listener
    爬取本blog所有文章链接
    90分钟掌握Python多线程爬虫(全程实战)
    python学习笔记
    Python零基础爬虫教学(实战案例手把手Python爬虫教学)
    开发,功能测试点,注意
    workerman
    tp6 文档
    公共方法
  • 原文地址:https://www.cnblogs.com/h2zZhou/p/4801241.html
Copyright © 2011-2022 走看看