RTC Forums

Subscription => Support => Topic started by: Theprasit on March 14, 2013, 05:11:24 AM



Title: Sending and receiving TObject descendants
Post by: Theprasit on March 14, 2013, 05:11:24 AM
First of all, Thank You for you great component I've love it so much.

Because of that, I expand my knowledge and idea to improve my project that came to this question.

I have an idea to send TObject descendent to rtc server and receive them back to client. I went thru a help manual and found a class with method "NewInstance", "asObject[]" but did not know how to use them.

Do you have a sample code on how to use the above methods to sending TObject such as TStrings between server and client?

Regards,

TS


Title: Re: Sending and receiving TObject descendants
Post by: D.Tkalcec (RTC) on March 14, 2013, 07:46:18 AM
You can not send any TObject over the wire, without having it serialized or implemented as a RTC Linked Object. The methods you have found, have a different purpose (see HELP file or description in the interface section for an explanation).

In order to send "Objects" over the wire, you have three options. You can either:

A) Use TRtcValue objects to define your object data (see THIS TOPIC (https://rtcforum.teppi.net/index.php?topic=311.0) for more details), or ...

B) Use some other method to serialize and deserialize your Object data. For example, many components and Forms can be serialized into a TStream by using their "SaveToStream" method and deserialized back into objects by using the "LoadFromStream" method. This is how Delphi Forms and DataModules are being stored inside the executable and loaded as a resource by Delphi.

Best Regards,
Danijel Tkalcec


Title: Re: Sending and receiving TObject descendants
Post by: Theprasit on March 17, 2013, 03:41:24 PM
So, what about "NewInstance" and "asObject[]". Could you please explain in more detail? A sample code is appreciate.

Thank You and Regards,

TS


Title: Re: Sending and receiving TObject descendants
Post by: cesarliws on March 19, 2013, 02:02:10 PM
Hi Theprasit,

- asObject: TRtcValueObject  is used to transport instances of TRtcValue or descendants.

Code:
procedure TLoginProvider.Execute(Sender: TRtcConnection; Param: TRtcFunctionInfo; Result: TRtcValue);
begin
  if User.Login(Param['UserName'], Param['Password'], TRtcDataServer(Sender).Session.ID) then
    Result.asObject := User.LoadInfo(Param['UserName']);
[...]
end;

In this example, Result.asObject will return a object instance with User information if the Login is OK.


Note: You must create a TRtcValue object to use asObject, it will use the internal implementation of RTC to stream the object, it is not using the new RTTI.


- NewInstance is a Vcl class function, used internally by Vcl when you call the constructor of the object.
  


Regards,


Cesar


Title: Re: Sending and receiving TObject descendants
Post by: Theprasit on March 21, 2013, 10:10:32 AM
Thank You for your answer, seem that I confuse about "NewInstance" with RTC "new..." functions :)

The cause of my question came from Oracle as I want to transfer Oracle CLOB field between Server and Client but not success. I tried both "asByteStream" as "asObject" but it return nothing.

After some searching, I found that cannot use CLOB but used BLOB instead. After change I can used "asByteStream" to transfer data as usual.

Again, Thank You for your RTC's Team great supporting.

TS


Title: Re: Sending and receiving TObject descendants
Post by: thomh on July 21, 2014, 07:52:15 PM
Quote
A) Use RTTI for Object serialization and de-serialization, as explained in the "Stream Objects using RTTI" example(s) by Cesar Romero in the RTC Classroom ( http://www.realthinclient.com/wp/?s=rtti ), or ...

Hello, I was interested in reading the above but it turns out to be a dead link. Is there an alternative link to these examples?

Thanks.
Thom


Title: Re: Sending and receiving TObject descendants
Post by: D.Tkalcec (RTC) on July 21, 2014, 10:52:45 PM
I've deleted the article about RTTI, because the implementation was very complex but it was still incomplete and the author had stopped working on it (lack of time and/or interest).

The short version is that you can implement custom serializers and deserializers for objects, so you can use the "SaveToStream" method to save your TObject into a TStream, which can be sent by using the rtc_Bytestream type (newByteStream / asByteStream). On the other side, you would need the "LoadFromStream" method to recreate the object from that Stream.

RTTI can be used in Delphi to access published object properties (and public, with extra compiler directives) for serialization and deserialization purposes, but there is no built-in mechanism in Delphi which would do that for all TObject descendants and their relations. There is a mechanism used by Delphi components to serialize and deserialize published properties and relations between components, but it only works for TComponent descendants and only for their published properties. That's basically what happens when you use the SaveToStream and LoadFromStream methods, which are provided by TComponent and all their descendants.

Best Regards,
Danijel Tkalcec


Title: Re: Sending and receiving TObject descendants
Post by: DougB on August 12, 2014, 07:01:47 PM
If you're interested in automatically serializing complex records or objects to a JSON string, which can be used with RTC, I'd recommend checking out the SynCommons.pas unit (native Windows) or related cross platform units from the mORMot project (http://blog.synopse.info).  

It makes this task trivial and is very high performance.  Make sure you get the code and documentation from the Trunk/unstable version section here (http://synopse.info/fossil/wiki?name=Downloads).  These files are updated every night, so you can keep going to this section on this page to download updates.

BTW, I see both mORMot and RTC as incredibly powerful frameworks, and use both for different purposes.

Doug