vrijdag 13 februari 2009

RemObjects SDK voor Delphi

RemObjects SDK is een Remoting Framework, waar onder andere eenvoudig WebServices mee gemaakt kunnen worden. Het is van het gelijknamige RemObjects.com . De laatste tijd is het vooral bekend geworden door Delphi Prism , omdat zij de Oxygene compiler geschreven hebben. RemObjects maakt nog meer mooie software: Hydra (.Net assemblies in Win32 gebruiken), Data Abstract , Pascal Script, etc. Niet alleen Delphi maar ook .Net (Visual Studio) wordt ondersteunt.
Ik heb geluk gehad dat ik bij mijn huidige detacheringsopdracht met deze mooie software in aanraking mocht komen :-).

De RO SDK is een beetje te vergelijken met WCF van .Net en DataSnap van Delphi. Maar het vooral veelzijdiger dan deze 2! Het is in principe taal onafhankelijk (C++, C#, php, Delphi maar ook FPC), meerdere platformen (Windows, Linux en MacOs!), ondersteunt verschillende formaten (binair, SOAP, JSON, XML, etc) en allerlei transporten (TCP, UDP, HTTP, mail, IPC, Messages, dll(!) etc). Daarnaast ondersteunt het verschillende vormen van encryptie en compressie. Juist deze brede ondersteuning biedt heel veel mogelijkheden, waarbij WebServices maar een van de vele is.

Ontwikkelen met de RO SDK is eenvoudig, globaal te verdelen in 4 stappen:

  1. Interface definieren in een aparte grafische tool
  2. Code wordt automatisch gegenereerd door de SDK
  3. Implementatie maken aan de server kant
  4. De interface aanroepen aan de client kant

Doordat de software mooi integreert met oa Delphi wordt je stap voor stap geholpen door middel van een wizard. Zo kan automatisch een server en client project aangemaakt worden, zodat je snel er mee kunt werken. Ook worden vele demos (inclusief handleiding en uitleg!) meegeleverd, zodat wat geavanceerde technieken eenvoudig geleerd kunnen worden. Ook de gegenereerde code is netjes gedocumenteerd. Alles is gewoon heel netjes afgewerkt!

Demonstratie

Om het een en ander toe te lichten, zal ik de stappen tonen waarmee je een nieuwe RO applicatie maakt.
Als eerste maken een nieuw project via File -> New -> Other:

Vervolgens kiezen we voor een VCL Standalone server (dit is het makkelijkst te testen):

Na het drukken op OK verschijnt een mooie wizard van RO:

Via de "Advanced Project Options" knop kunnen wat meer instellingen aangepast worden:

Na het drukken op OK hebben we een nieuwe Project Group met een server en client project.

Cliënt

De client bestaat uit een channel (in dit geval een TCP client), een message (binair formaat) en een remote service waarmee we de functies aan de server kant mee kunnen aanroepen:

Server

De server bestaat uit een TCP server en message component (binair formaat):

Standaard staat alles al goed ingesteld, tijd om de "service interface" te bekijken.

Service Interface

Om de interface te bekijken of aan te passen, klikken we op "Edit Service Library" in het "RemObjects SDK" menu:

Vervolgens verschijnt de Service Builder, met default de volgende interface:

Zoals je ziet in de bovenstaande screenshot, kun je hier je eigen structures, enumerations en arrays maken. Deze types kunnen als parameter of result van een functie gebruikt worden. Ook kunnen custom exceptions gedefinieerd worden en asynchrone events gemaakt worden. Het mooie van deze types en definities is dat deze ook als fixed types in code gebruikt kunnen worden!

Server Code

Zodra het project gecompileerd wordt (of via het RO menu) wordt vanuit de Service Definitie de code gegenereerd. Voor elke "service" wordt een RO Datamodule aangemaakt:

Verder wordt een "invoker" unit, "interface" unit (met alle types) en een "implementation" unit gemaakt. De eerste 2 units worden elke keer automatisch ververst en hoeven niet aangepast te worden. Alleen de implementatie moet uiteraard zelf gemaakt worden, zoals in dit geval voor de "Sum" en "GetServerTime" functies:

Client Code

Het enige wat we nu nog moeten doen is een paar knoppen toevoegen aan de client, zodat we server functies kunnen aanroepen:

procedure TClientForm.btnServerTimeClick(Sender: TObject);
var dtServer: TDateTime;
begin
dtServer := (RORemoteService as INewService).GetServerTime;
lblServerTime.Caption := DateTimeToStr( dtServer );
end;

procedure TClientForm.btnSumClick(Sender: TObject);
var iSum: integer;
begin
iSum := (RORemoteService as INewService).Sum( edtA.Value, edtB.Value );
edtSum.Text := IntToStr( iSum );
end;

Als laatste builden we de beide projecten.

Uitvoeren

Om onze code te testen, starten we als eerste via het RO menu de server:

Het eenvoudige scherm van de server verschijnt, waarna we de client kunnen starten (zie onder voor server en client):

Zoals je ziet werkt de code uitstekend :-). En dat met maar 6 regels code!

Geen opmerkingen: