big streams with DataSnap

datasnap, delphi, stream

Solution

Actually, i think i`ve got it. I'm posting this as an answer maybe somebody else need this.

procedure TfrmMain.butStreamClick(Sender: TObject);
const
  iBufSize = 128;
var
  sStr : TStream;
  sMem : TMemoryStream;
  buf: PByte;
  iRead: integer;
begin
  cycleConnection;

  with TsrvMethodsClient.Create( SQLConn.DBXConnection, False ) do begin

    sStr := getStream( 500000 ); //500k stream

    GetMem(buf, iBufSize);
    sMem := TMemoryStream.Create;
    try
      repeat
        iRead := sStr.Read( Pointer(buf)^, iBufSize);

        if iRead > 0 then sMem.WriteBuffer( Pointer(buf)^, iRead);
        if iRead < iBufSize then break;
      until iRead < iBufSize;
    finally
      FreeMem(buf, iBufSize);
    end;

    Free;
  end;
  FreeAndNil(sStr);
  FreeAndNil(sMem);
end;

P.S.

Searching through DataSnap code samples i`ve found that one (speed related) improvement would be to have iBufSize set to 61440 (or equivalent hex value $F000) which seems to be the biggest size can be received in one go. If receiving stream is bigger then reported size will be -1 and the code above is needed to read the entire stream.

Problem

I'm trying to transfer some big streams (~1Mb) between DataSnap server/client but to no avail. I'm trying to understand the code of Jim Tierney (http://blogs.embarcadero.com/jimtierney/2009/04/06/31461) with no luck and i can't even compile the code because of a missing library, anyway ... The max size of a stream i`m able to receive is 64k, so any tips/ideas/code samples you can provide for a weekend programmer like me will be very welcomed. Thank you! my server code: ``` function TsrvMethods.getStream(iCount: integer): TStream; begin Result := dummyStream('0123456789', iCount); end; function dummyStream(sCnt: string; iCount: integer): TStream; begin Result := TMemoryStream.Create; while iCount > 1 do begin Result.Write(Pointer(sCnt)^, Length(sCnt)); Dec(iCount); end; Result.Seek(0, TSeekOrigin.soBeginning); end; ``` my client calling code: ``` procedure TfrmMain.butStreamClick(Sender: TObject); var sStr : TStream; begin cycleConnection; //make sure we have an active connection with TsrvMethodsClient.Create( SQLConn.DBXConnection, False ) do begin sStr := getStream( Integer(SpinCount.Value) ); Free; end; FreeAndNil(sStr); end; ```

Original source