RTC Forums
May 23, 2024, 01:30:25 AM *
Welcome, Guest. Please login or register.

Login with username, password and session length
 
   Home   Help Login Register  
Pages: [1]
  Print  
Author Topic: sending over an record  (Read 5159 times)
Henk vd Boogaard
RTC Expired
*
Posts: 24


« on: December 31, 2015, 10:33:22 AM »

Hello,
I have a Tablet running a NexusDB embedded database
I want to send one record from that database to an extern server, and there translate that to another NexusDB database.
The record contains also Graphic blobs.
How can I do that.
I was storing it in a xml file and send that over, but the blobs gave errors (asstring).
Can I store the record in a one record Memory table and sent it over to the server?
And how do I do that.
I am far from an expert in Delphi so please be clear in an example.

Thanks in advance,
Henk van den Boogaard
Logged
D.Tkalcec (RTC)
Administrator
*****
Posts: 1881


« Reply #1 on: December 31, 2015, 11:13:23 AM »

When sending binary data as RTC remote function parameters, you should either use the "asByteArray" or "asByteStream" RTC types. "asByteArray" is a dynamic byte array, "asByteStream" is a TMemoryStream.

If you need examples on copying data between a TDataSet and a TRtcDataSet or TRtcArray, take a look at the "rtcDB.pas" unit, where you can find these functions (among others):

// Copy data from a Delphi TDataSet into a TRtcDataSet (used for transport)
procedure DelphiDataSetToRtc(DelphiDS:TDataSet; rtcDS:TRtcDataSet; ClearFieldDefs:boolean=True; OnlyDataFields:boolean=True);

// Copy data from a Delphi TDataSet into a TRtcArray of TRtcRecords (used for transport)
procedure DelphiDataSetToRtcArray(DelphiDS:TDataSet; rtcArr:TRtcArray; OnlyDataFields:boolean=False);

// Copy field definition from a TRtcDataSet (used for transport ) to a Delphi TDataSet
procedure RtcDataSetFieldsToDelphi(rtcDS:TRtcDataSet; DelphiDS:TDataSet);

// Copy data rows from a TRtcDataSet (used for transport) to a Delphi TDataSet
procedure RtcDataSetRowsToDelphi(rtcDS:TRtcDataSet; DelphiDS:TDataSet);

Copy the code you need into your own unit and modify it (if needed) to work with Databse Access components of your choice.

For more examples on working with RTC structures, check this FAQ topic.

Best Regards,
Danijel Tkalcec
Logged
Henk vd Boogaard
RTC Expired
*
Posts: 24


« Reply #2 on: January 01, 2016, 05:27:28 PM »

Hi Danijel,

I have made the code below.
Wil you please check of this is correct?

How do I get the records in the memory table?

// CODE IN THE CLIENT (TABLET)
procedure TStartscherm.VerstuurWerkopdrachtenKlaar;
var
  URL_str: string;
  IdHTTP_Verstuur: TIdHTTP;
begin
  rtcDS:=TRtcDataSet.Create;
  DM1.nxQ_AantalOpdrachtenTeVersturen.Open; {= nxQuery}
  if DM1.nxQ_AantalOpdrachtenTeVersturen.RecordCount > 0 then
  begin
     // URL aanroep: http://80.61.179.222:22333/tbid_wtr1?xx=DF45  - xx=tabletID
     URL_str := 'http://' + DM1.nxT_TabletID.FieldByName('Webserver_Z').AsString + ':' + DM1.nxT_TabletID.FieldByName('Poort')
          .AsString + '/TBID_WO_Retour1?xx=' + DM1.nxT_TabletID.FieldByName('Tablet_ID').AsString;
     DelphiDataSetToRtc(DM1.nxQ_AantalOpdrachtenTeVersturen, rtcDS, False, True);
     IdHTTP1.Post(URL_str, rtcDS.asByteStream['RecordStrm']);
     DM1.nxQ_AantalOpdrachtenTeVersturen.Close;
  end;
end;

// CODE IN THE SERVER SERVICE

procedure TWork.DP_WerkopdrachtenRetourCheckRequest(Sender: TRtcConnection);
var
  TBID: string;
  test: string;
begin
  with Sender as TrtcDataServer do
  begin
    // test := UpperCase(Request.FileName);
    // URL aanroep: http://80.61.179.222:22333/tbid_b1?xx=DF45  - xx=tabletID
    if Request.FileName = '/TBID_WO_Retour1' then
    begin
      TBID := Request.Query.ItemValue[0];
      TBID3 := TBID;
      if DM1.nxT_Tablet_IDs.FindKey([TBID]) then
        if DM1.nxT_Tablet_IDs.FieldByName('Actief').AsBoolean then
          Accept;
    end;
  end;
 
  procedure TWork.DP_WerkopdrachtenRetourDataReceived(Sender: TRtcConnection);
var
  iChildL1, iStatus, iNodeBerichten, iNodeBericht: IXMLNode;
  BerichtenQuery: string;
  XML_aanvraag: RtcString;
  XMLDoc4, XMLDoc9: TXMLDocument;
  XML_bericht: RtcString;
  rtcDS : TRtcDataSet;
  nxMT : TnxMemTable;
begin
  try
    with Sender as TrtcDataServer do
    begin
      if Request.Complete then
        try
         rtcDS := TRtcDataSet.Create;
         nxMT := TnxMemTable.Create;
         nxMT.Open;
         rtcDS.asByteStream[Server. <================???
         RtcDataSetFieldsToDelphi(rtcDS, nxMT);
        except
          on E: Exception do
        end;

    end;
  finally
    rtcDS.Free;
    nxMT.Free;
  end;
end;
Logged
D.Tkalcec (RTC)
Administrator
*****
Posts: 1881


« Reply #3 on: January 01, 2016, 05:51:35 PM »

Using the code you've posted above for the Client side, you are only sending a single BLOB field to the Server. I’m not familiar with Indy, but if you can replace the Indy line for posting the request on the Client side with something like this ...

IdHTTP1.Post(URL_str, rtcDS.toJSON);

... (am assuming Indy has a method for sending the request content body as a string) you will be sending the complete DataSet stored in "rtcDS" to the Server and not just a single BLOB field.

To get that data back into a TRtcDataSet on the Server side, you can use this:

rtcDS:=TRtcDataSet.FromJSON(Read);

NOTE: "Read" is a method of the Sender:TRtcConnection component returning the request content body which is currently stored in the receiving buffers for that connection.

Best Regards,
Danijel Tkalcec
Logged
Henk vd Boogaard
RTC Expired
*
Posts: 24


« Reply #4 on: January 03, 2016, 07:20:22 PM »

Hi Danijel,

I have done as you proposed and tryed to post it with indy, but that gives errors.
So I decided to use your RtcHttpClient.
But I don not kwow how to do this and in the examples I also could not find it.
Wil you please help me again?

My code so far is:

procedure TStartscherm.VerstuurWerkopdrachtenKlaar;
var
  URL_str: string;
  rtcDS: TRtcDataSet;
begin
  DM1.nxQ_AantalOpdrachtenTeVersturen.Open;
  if DM1.nxQ_AantalOpdrachtenTeVersturen.RecordCount > 0 then
  begin
    rtcDS := TRtcDataSet.Create;
    try
      // URL aanroep: http://80.61.179.222:22333/tbid_wtr1?xx=DF45  - xx=tabletID
    //  URL_str := 'http://' + DM1.nxT_TabletID.FieldByName('Webserver_Z').AsString + ':' + DM1.nxT_TabletID.FieldByName('Poort')
     //   .AsString + '/TBID_WO_Retour1?xx=' + DM1.nxT_TabletID.FieldByName('Tablet_ID').AsString;
      // IdHTTP1.Post(URL_str, rtcDS.toJSON);     <--Gives an error of not finding the table

      DelphiDataSetToRtc(DM1.nxQ_AantalOpdrachtenTeVersturen, rtcDS, True, True);
      RtcHttpClient1.ServerAddr := DM1.nxT_TabletID.FieldByName('Webserver_Z').AsString;
      RtcHttpClient1.ServerPort := DM1.nxT_TabletID.FieldByName('Poort').AsString;

     // Where goes:
         '/TBID_WO_Retour1?xx=' + DM1.nxT_TabletID.FieldByName('Tablet_ID').AsString;
     // how to send it with:
     RtcHttpClient1

    finally
      rtcDS.Free;
    end;

  end;
end;
Logged
D.Tkalcec (RTC)
Administrator
*****
Posts: 1881


« Reply #5 on: January 03, 2016, 10:02:25 PM »

You need a TRtcDataRequest or TRtcClientModule to send requests from a Client to the Server, just like you need a TRtcDataProvider or TRtcServerModule+TrtcFunctionGroup+TRtcFunction on the Server to process those requests there. All of this is already covered in Quick Start Lessons and FAQ Topics. Working with RTC remote functions is covered in this Quick Start Topic and related FAQ topics.

Very short and simple Remote Function Client and Server Examples can be found in the QuickStart\RemoteFunctions folder. These two short examples only send a single parameter in each remote function call, but you can send any number of parameters of any type the exact same way.

Best Regards,
Danijel Tkalcec
Logged
Henk vd Boogaard
RTC Expired
*
Posts: 24


« Reply #6 on: January 04, 2016, 05:19:24 PM »

I thought I found it, but gives a parameter error.

procedure TStartscherm.VerstuurWerkopdrachtenKlaar;
var
  URL_str: string;
  rtcDS: TRtcDataSet;
begin
  DM1.nxQ_AantalOpdrachtenTeVersturen.Open;
  if DM1.nxQ_AantalOpdrachtenTeVersturen.RecordCount > 0 then
  begin
    rtcDS := TRtcDataSet.Create;
    try
      // URL aanroep: http://80.61.179.222:22333/tbid_wtr1?xx=DF45  - xx=tabletID
      DelphiDataSetToRtc(DM1.nxQ_AantalOpdrachtenTeVersturen, rtcDS, True, True);
      RtcHttpClient1.ServerAddr := DM1.nxT_TabletID.FieldByName('Webserver_Z').AsString;
      RtcHttpClient1.ServerPort := DM1.nxT_TabletID.FieldByName('Poort').AsString;
      with RtcDataRequest1.Request do
      begin
        Method := 'POST';
        Host := DM1.nxT_TabletID.FieldByName('Webserver_Z').AsString;
        FileName := '/TBID_WO_Retour1?xx=' + DM1.nxT_TabletID.FieldByName('Tablet_ID').AsString;
      end;
      RtcDataRequest1.Post(rtcDS.to_JSON);
    finally
      rtcDS.Free;
    end;

  end;
end;
Logged
D.Tkalcec (RTC)
Administrator
*****
Posts: 1881


« Reply #7 on: January 04, 2016, 07:54:01 PM »

If you want to do the same with RTC what you've previously tried with Indy (using plain HTTP requests), take a look at the QuickStart\ClientUpload example. Or ... if you want to use remote functions, please follow Quick Start lessons and examples I've mentioned in my previous reply.

Best Regards,
Danijel Tkalcec
Logged
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2015, Simple Machines Valid XHTML 1.0! Valid CSS!
Page created in 0.031 seconds with 16 queries.