0

I am using datasnap technology where I got a client a server application. The Server gets the data from database and puts into stream which is then fetched at client side. I keep getting a "Missing Data Provider or Data Packet" error on the client side code.

Server side code:

function GetFiles(ClientID: integer): TStream;
var
  CDS: TClientDataSet;
begin
  try
  Result := TMemoryStream.Create;
  CDS := TClientDataSet.Create(nil);
  with adsFiles do   // ads is adodataset and dspFiles is the dataset provider which has its dataset property set to adsFiles
  begin
    Close;
    Parameters.ParamByName('ClientID').Value := ClientID;
    Open;
    CDS.Data :=  dspFiles.Data;
    CDS.Open; 
    CDS.SaveToStream(Result);
    Result.Position := 0;
  end;
  finally
    CDS.Free;
  end;

Client Side Code:

procedure ExportData;
var
   StreamData: TStream;
begin
    StreamData := SvrMethodClass.GetFiles(AClientID);
    StreamData.Seek(0,soFromBeginning);
    StreamData.Position:= 0;
    cdsClientFiles.LoadFromStream(StreamData); // getting the error message "Missing Data Provider or Data Packet" 
    cdsClientFiles.Open;
end;

Client side I have dropped a clientdataset component and trying to load the data into this dataset where the issue is raised any help pointing me where I am going wrong would be really appreciated. Thanks

similar question: Streaming TClientDataSet using Datasnap in Delphi XE6 checked the solution but it did not work out

mano
  • 308
  • 3
  • 19
  • Read the comments on the q you linked, then do some debugging, Readers who cannot reproduce your problem are unlikely to be able to help you, so provide an MCVE. Meanwhile, -1. – MartynA Nov 02 '17 at 10:19
  • Btw, you are not checking whether `ads` returns any rows. Is that intentional? – MartynA Nov 02 '17 at 10:40
  • @MartynA I checked server side I can see it returns rows and I even tried to save the data to xml and it is 204MB. – mano Nov 02 '17 at 10:42
  • The problem here, at least from my experience, is where you do this `CDS.Data := dspFiles.Data;`. I can't imagine why you would do this, since it's completely unnecessary. – Freddie Bell Nov 02 '17 at 12:12
  • 2
    Btw, there seems to be a long-standing problem retrieving streams over Datasnap. See, e.g., https://stackoverflow.com/questions/41854631/cant-retrieve-tstreams-bigger-than-around-260-000-bytes-from-a-datasnap-server – MartynA Nov 02 '17 at 16:38
  • 1
    @MartynA Thanks for pointing this out. after adding the following lines at client side before cdsClientFiles.LoadFromStream(StreamData) I was able to get the issue resolved cdsClientFiles.CreateDataSet; cdsClientFiles.Close; But not able to get the data as its bigger in size.. – mano Nov 03 '17 at 05:18
  • @MartynA I modified the query to fetch only one row from database and I can see it client side but when it goes above 1 row(which had pdf as blob) client side I cannot see data . this clearly tells that stream in datsnap model not able to get large data. Any idea ho I can get this done? I am at a crucial point where lot of time is invested .. any direction really appreciated. – mano Nov 03 '17 at 09:10
  • Well, my experiments at the time I commented on the other q (or maybe another similar one) showed that there is no similar problem when the data returned from the server is a string rather than a stream. So I suggested that the user returned the "blob" as a Base64-encoded string. – MartynA Nov 03 '17 at 09:27
  • @MartynA Ys you are right. In that example it has got Firedac component which allows creating blob of the entire dataset data. In ADO client dataset I have been looking for the same could not find it. It has CreateBlobStream which takes only a single column. In my case I want to get other columns as well in short entire dataset. – mano Nov 03 '17 at 12:06
  • In that case, you could probably avoid using Base64 - see update to my answer. – MartynA Nov 03 '17 at 12:15
  • @MartynA Ok will check and let you know. thanks – mano Nov 03 '17 at 12:58

1 Answers1

1

I spent a lot of time investigating the problems with returning data as a stream from a datasnap server - see e.g. Can't retrieve TStreams bigger than around 260.000 bytes from a Datasnap Server, but was unable to come up with a satisfactory solution for stream data.

However, experiments revealed that a similar problem does not occur with string data (I tested strings up to several hundred megabytes). So, I would suggest you try sending your binary/blob data from the Datasnap server as a Base64-encoded string.

Of course, if a string representation of your ADO or CDS data is adequate for what you want, one way to achieve that would be to do an adsFile.SaveToFile(..., pfXML) or CDS.SaveToFile(... dfXML) in the server method, then return the resulting file as a string.

MartynA
  • 30,454
  • 4
  • 32
  • 73
  • I accept this answer however this would give out of memory issue server side. I am able to get the task from server side on data set level where keep the reference of primary key in one data set and later at each iteration export a single file with blob data from another data set. Thanks for the help:) – mano Nov 07 '17 at 08:00