Icon View Thread

The following is the text of the current message along with any replies.
Messages 1 to 9 of 9 total
Thread RemObjects SDK and EWB data
Wed, Dec 18 2013 10:09 AMPermanent Link

Eivind

All

I have successfully set up one site with EWB using Delphi and IndyHTTP Server. Many of you guys here are using RemObjects SDK on the server side, and my next project has a budget for purchasing a license for RemObjects.

I can see one demo project where the EWB app only calls a simple function to return a number. That really don't give my much to go on as I need to present data, and have the user add, edit and delete data in a mySql database. As far as I understand, using RemObject you have to link with a JavaScript library to invoke server functions. What is the best practice for using RemObjects? If I understand it correct, you cannot use Database.Load() and Database.Commit() as they call an url directly. If you have to invoke JavaScript functions to transmit the JSON data, do you define one server function to get data and function to commit data?

Any guidance on how to use RemObject would be appreciated

Eivind  
Wed, Dec 18 2013 11:09 AMPermanent Link

Robert Devine

You need to use Data Abstract rather than just Remobjects (DA is built
on top of RO messaging). It's been a while since I used it but with
DA/Javascript you get the same approach as in the Delphi version - i.e.
you make changes to the client-side datasets then call ApplyUpdates
which sends the deltas to the RO/DA server.

I wrote some code that copies values to and from the EWB/DA datasets so
that I could display the data in an EWB grid. It all works pretty well.
I think there are others on the newsgroup who are still actively using
RO/EWB who might have more details.

There's a simple DA demo on the Demos newsgroup.

Cheers, Bob




On 18/12/2013 15:09, Eivind wrote:
> All
>
> I have successfully set up one site with EWB using Delphi and IndyHTTP Server. Many of you guys here are using RemObjects SDK on the server side, and my next project has a budget for purchasing a license for RemObjects.
>
> I can see one demo project where the EWB app only calls a simple function to return a number. That really don't give my much to go on as I need to present data, and have the user add, edit and delete data in a mySql database. As far as I understand, using RemObject you have to link with a JavaScript library to invoke server functions. What is the best practice for using RemObjects? If I understand it correct, you cannot use Database.Load() and Database.Commit() as they call an url directly. If you have to invoke JavaScript functions to transmit the JSON data, do you define one server function to get data and function to commit data?
>
> Any guidance on how to use RemObject would be appreciated
>
> Eivind
>
Wed, Dec 18 2013 11:18 AMPermanent Link

Matthew Jones

I will probably miss bits out, but feel free to ask when you get stuck!

Fundamentally, the RO SDK is all about defining an "interface" and then just
calling that. In Delphi, it looks and feels just like calling any object member,
but they do the magic to send it over the wire. With EWB, due to the javascript,
you have to be a little more involved due to having to handle the callbacks -
everything is async. So you make the call, and get on with something useful until
the callback occurs.

The key is to create a Delphi service application, and then use the RemObjects
"Edit Service Library" facility to define the functions that you want to be able to
call. You can change these later if you want, though once you have something
shipping you need to keep it stable, so you end up adding more instead of replacing.
I tend to have a "GetServerStatus" function to call first to which I pass client
info, including a "protocol number" (integer) which the server can check. If the
server can't handle some version, return a fail and the client then tells the user
an upgrade is needed before it can work. For most situations this isn't actually
needed, as the application came from the server just a moment before, but it helps
with caches and PhoneGap etc.

Once you have your functions, save the library, and do a build. RemObjects will
offer to make a data module (choose the custom type) and it all gets linked up for
you. You just fill in the templated functions with what you want them to do. I tend
to put try/except's around them to stop them going back to the client. Allows me to
log etc better.

Then, go back to the library definition, and use the CodeGen menu to output the
javascript. You then add that to your EWB project as an addional file.

The basic setup for EWB use is easy if you follow the sample that someone posted
(thanks again!). You just have to follow that, and define the various functions and
callbacks. One day I must automate that somehow. You have to get the parameters
right, otherwise the EWB type checking fails (because ROSDK/Javascript isn't
strictly typed). Oh yes, I always use the UTF8String in ROSDK for any strings, XML
or JSON. It hasn't failed me yet. I've not used the RO binary in EWB. If you have a
function defines with two "in" variables and two "out", then you wind up with two
function definitions, one for the send to the server with the ins and completion
routines, one for the response with the outs and result status. If you have an
in/out variable, it appears in both.

Then you have to look into whether you want to have authentication. You could do
this yourself, or you can use the RO SDK session management. This is documented on
the RS site, but basically you define your main service, and on the data module you
set it to need a session. You then have another login service, and that doesn't
need a session. This is my simple version:

function TLoginService.Login(const Information: AnsiString): Boolean;
begin
   result := (Information = 'secret');
   if not result then
   begin
      DestroySession;
   // Informs the SessionManager to discard the
   // session because the login failed
   end
   else
   begin
      Session;
   end;
end;


procedure TLoginService.Logout;
begin
   DestroySession; // Discards the session
end;

In the EWB code, where the Channel and Message are created, I add
   FChannel.onLoginNeeded := OnServerLoginNeeded;

procedure TMyForm.OnServerLoginNeeded(aCallBack : TOnSuccessCallbackEx);
begin
   Report('Called back');
   m_pfnLoginRetry := aCallBack;
   DoLogin;
end;

procedure TfrmJoin.DoLogin;
begin                        
   try
   Report('Logging in');
   m_bLoggedIn := false;   // safe assumption surely?
   if FLoginSrvc = nil then
       FLoginSrvc := TLoginService.Create(FChannel, FMessage, 'LoginService');
   FLoginSrvc.Login('secret', OnServerLoginComplete, OnLinkError);
   Report('Called Logging in');
   except
       on errInfo : EError do
       begin
           SetStatus('DoLogin Error ' + errInfo.Message, true);
       end;
   end;
end;

procedure TfrmJoin.OnServerLoginComplete(nResult : Integer);
begin                                      
   try
   Report('Login response ' + IntToStr(nResult));
   if nResult = 1 then
   begin
//        m_bLoggedIn := true;
       if assigned(m_pfnLoginRetry) then
       begin
           Report('Found retry fn');
           m_pfnLoginRetry(0);
           m_pfnLoginRetry := nil;
           Report('Called retry fn');
       end
       else
       begin
           Report('No retry fn');
//            RunStateMachineEx(STATE_SOMETHING);
       end;
   end
   else
   begin
SetStatus('Sorry, the account details are not recognised. Please try
again.');
   end;
   except
       on errInfo : EError do
       begin
           SetStatus('OnServerLoginComplete Error ' + errInfo.Message, true);
       end;
   end;
end;

Now, as it happens I then do later authentication for some applications, having
asked the user for an account, but you can choose how you manage that.

I hope that this helps.

/Matthew Jones/
Wed, Dec 18 2013 11:24 AMPermanent Link

Matthew Jones

Hmm, I never used DA - I always thought it was too abstract for my use, and my
databases are not really grid fodder. That said, I have used my own JSON to feed
into the EWB data storage, but all in my own custom format. I basically prefer to
define a set of functions to achieve the purpose in an interface, instead of having
a database that the client does the clever stuff with.

But if it works for others, I'm sure it is good - there's no one right way.

/Matthew Jones/
Wed, Dec 18 2013 11:45 AMPermanent Link

Robert Devine

I've used both approaches in Delphi but eventually just used DA all of
the time. It really is very powerful out-of-the-box for typical CRUD
apps and saves a ton of work on the server side in comparison to just
using RO.

Cheers, Bob


On 18/12/2013 16:24, (Matthew Jones) wrote:
> Hmm, I never used DA - I always thought it was too abstract for my use, and my
> databases are not really grid fodder. That said, I have used my own JSON to feed
> into the EWB data storage, but all in my own custom format. I basically prefer to
> define a set of functions to achieve the purpose in an interface, instead of having
> a database that the client does the clever stuff with.
>
> But if it works for others, I'm sure it is good - there's no one right way.
>
> /Matthew Jones/
>
Wed, Dec 18 2013 11:59 AMPermanent Link

Matthew Jones

>  It really is very powerful out-of-the-box for typical CRUD
> apps and saves a ton of work on the server side in comparison to
> just using RO.

That's where my stuff is different I guess - I don't do the CRUD stuff at all
really. Much more send information, process it with other info, and then output
that to another client somehow.

I look forward to being able to show my latest creation off. Unlike the web service
that we then killed, this is a Window desktop app that uses web clients for input.
I'm really enjoying making it.

/Matthew Jones/
Thu, Dec 19 2013 12:02 PMPermanent Link

William Sigmund

> I look forward to being able to show my latest creation off ... this
is a Window desktop app that uses web clients for input.  I'm really
enjoying making it.

Could you say a bit more about the technologies you are using for each
bit?

Thanks

William
Fri, Dec 20 2013 5:00 AMPermanent Link

Matthew Jones

> Could you say a bit more about the technologies you are using for
> each bit?

Fairly simple really. My previous project had a windows service from a RemObject
SDK interface. All my services have a "test harness" plain application that I can
use to debug more easily, which just creates the service and starts it up (and
closes down nicely etc). In that project I also had a user interface app that talks
to the service over the RO interface to control it. For my new project, I've
combined the control app and the test harness because this is designed to be a
desktop application that you can start up easily, then it talks to another
application (imagine it talks to an Excel spreadsheet to read/store data) and then
allows people in a meeting to use their phones, tablets, laptops to connect to the
new application to add content. The EWB application is delivered by the RO SDK web
server, and then it talks to the RO SDK service to get relevant data (both as plain
parameters, and JSON for more complex info). The EWB app is smart enough to handle
lost connections and restarting the desktop application, so that network issues are
not a problem. The desktop application has a window that can be used as a central
screen on a projector, and that uses either Delphi code, or a Chromium browser
embedded to show the same EWB application. The embedded browser starts the EWB
application with a "?presenter=enable" parameter in the URL, which tells it to work
in display mode and not user mode, and thus alters behaviour. This allows me to
have a common display for key parts, rather than have to make the Delphi UI look
the same but with inevitable slight differences. The hooking up is sort of complex,
but also simple. I'm trying to keep the logic done best where it fits. For example,
I need to work out an average and standard deviation from the input data. The data
is fed from the user's EWB, through the service, and out to the presenter. I figure
that the same calculation code could be in either the service or the EWB
application, but will run faster in the service. Thus that is what will do it, and
pass the result to the EWB application in the JSON. However, the display of the
data is down to the EWB application as that knows the screen resolution etc. so if
it has to combine values in a graph, then it can do it without affecting the
average.

It is all quite good fun really.

/Matthew Jones/
Fri, Dec 20 2013 11:20 AMPermanent Link

William Sigmund

Interesting! Thanks for taking the trouble.

William
Image