John
John

Reputation: 507

How to pass and return a Stream using DataSnap in Delphi XE6?

How to pass and return a Stream using DataSnap in Delphi XE6?

When I call my server side method, my stream is the correct class, has a size, and position. However, it when it comes accross to my client, the class is not what I expected, and it has no size or position

//Client side code

 procedure TForm1.brnGetReportClick(Sender: TObject);
    var
      RunReportObj: TRunReportObject;
      S: TStream;
      FS: TFileStream;
    begin
       ....
       try
          S:= (ClientModule1.ServerMethods1Client.getReport(RunReportObj));
          //ShowMessage('Class = ' + S.ClassName + #10#13 +
          //            'Size = ' + intToStr(S.Size) + #10#13 +
          //            'Position = ' + intToStr(S.Position));
          S.Position:= 0;
          FS:= TFileStream.Create('test.rpt', fmCreate or fmOpenWrite);
          FS.Position:= 0;
          try
            FS.CopyFrom(S, S.Size);
          finally
            FS.Free;
          end;
        finally
          S.Free
        end;
    end;

My debugging showmessage in the code above, displays the following

Class = TDBXStreamReaderStream
Size = -1
Position = 0

//server side method

function getReport(const ARunReportObj: TRunReportObject): TStream;
var
  r: String;
  SS: TStringStream;
begin

   result:= TMemoryStream.Create;

   r := getRunReportJSON(ARunReportObj);
   SS := TStringStream.Create(r, TEncoding.ASCII);
   try
     try       
       ServerContainer1.idHttp1.Post
('https://imserver1.runit.com/isapi/isellitreporttest.dll/isellit', SS, result);
      ShowMessage('Class = ' + Result.ClassName + #10#13 +
                  'Size = ' + intToStr(result.Size) + #10#13 +
                  'Position = ' + intToStr(result.Position));
        Result.Position:= 0;
     except
     end;
   finally
    SS.Free;
   end;
end;

My debugging showmessage in the code above, displays the following

Class = TMemoryStream 
Size = 373760 
Position = 373760

Upvotes: 3

Views: 2732

Answers (2)

Antonio Barbosa
Antonio Barbosa

Reputation: 1

Server:

client to server

function Tform_methodos.SendStream(st:TStream): string;
var sm : TMemoryStream;
begin
    ...
    sm:=TMemoryStream.create;
    sm.LoadFromStream(st);
    sm.SaveToFile(pasta+'\test.bin');
    sm.free;
end;

server to client:

function Tform_methodos.GetStream(var size : integer):Tstream;
begin
    ...
    result:=TmemoryStream.create;
    TmemoryStream(result).LoadFromFile('test.bin');
    size:=TmemoryStream(result).Size;
end;

Client: client to server

var sm : TMemoryStream
    error : string;
begin
    ...
    sm:=TMemoryStream.create;
    sm.LoadFromFile('test.bin');
    error:=server.SendStream(sm);
    sm.Free;
end;

server to client

var sm : TmemoryStream;
    st : TStream;
    size : integer; 
begin
    ...
    sm:=TMemorystream.create;
    st:=server.GetStream(size);
    sm.CopyFrom(st,size);
    sm.SaveToFile('test.bin');
    sm.free;
end;

Upvotes: 0

Uwe Raabe
Uwe Raabe

Reputation: 47704

That is as designed. DataSnap only guarantees that you get a TStream from the server, not which class it actually is. You can read from it, but that is it.

Position = 0 is also expected, as that is what you set it in the server. On the other side, I am not sure if anything else as Position = 0 is useful at all, so I would'nt be surprised if you get Position = 0 on the client side anyway. Although, the stream my not start at the expected position when the server doesn't set it to 0 before.

For the Size property I refer to the TStream documentation:

The Size property typically indicates the size of the stream in bytes. But a descendent of TStream can use -1 to indicate an unknown size. When the size is unknown, use the return value from TStream.Read to determine end of the stream.

You should be aware that DataSnap will not necessarily transfer the stream content with the call to getReport, but may do so when you call Read from the client side. This allows for something like endless streams like a movie or radio podcast.

Upvotes: 4

Related Questions