Blog

All Blog Posts  |  Next Post  |  Previous Post

TMS WEB Core: a bridge to the future!

Wednesday, October 24, 2018

Intro
While working in the TMS Labs this week, we had a fruitful discussion on how we could interact with a desktop or mobile environment, where the browser that hosts a TMS WEB Core application, runs on. We already had some experience creating a JavaScript bridge between a TWebBrowser and Google Maps (https://www.tmssoftware.com/site/webgmaps.asp) and figured out this could be useful for TMS WEB Core as well. We wanted to give the user the capability of hosting its TMS WEB Core application in a native desktop or mobile application that offers access to all of the operating system functionality and make it accessible via the browser.

Finding an entry point
We created a TTMSFNCWebCoreClientBrowser class that acts as the communication and viewing component for a TMS WEB Core application. To setup the communication, we needed an entry point. In JavaScript, a global variable can be defined and that was just the entry point we were looking for. In TMS WEB Core, during the creation of TApplication, we also injected a global variable "TMSWEBCoreClientBrowser", that is initialized with a string "unknown". This variable is filled in, when the TTMSFNCWebCoreClientBrowser establishes a conection to the TMS WEB Core application.
  if ExecuteJavascript('document.readyState', true) = 'complete' then
  begin
    if ExecuteJavascript('window.TMSWEBCoreClientIdentifier', true) = 'unknown' then
      FInitialized := True;
  end;
Handshake
After the initialization is complete, the TTMSFNCWebCoreClientBrowser instance performs a handshake. This is being done by executing JavaScript. The HandshakeScript is dynamically being added during the initialization of the TMS WEB Core Application and initializes the TMSWEBCoreClientIdentifier global variable.
initialization
begin
  HandShakeScript := TJSHTMLScriptElement(document.createElement('script'));
  HandShakeScript.id := 'HandShakeScript';
  HandShakeScript.type_ := 'text/javascript';
  HandShakeScript.innerHTML :=
  'var TMSWEBCoreClientIdentifier = "unknown";'+#13#10+
  'function HandShake(cid){'+#13#10+
  '  TMSWEBCoreClientIdentifier = cid;'+#13#10+
  '}';
  document.body.appendChild(HandShakeScript);

  Application := TApplication.Create(nil);
end;
The handshake script is being called from the TTMSFNCWebCoreClientBrowser instance after the initialization is complete.
procedure TTMSFNCCustomWebCoreClientBrowser.PerformHandshake;
var
  c: string;
begin
  {$IFDEF MSWINDOWS}
  c := 'windows';
  {$ENDIF}
  {$IFDEF MACOS}
  {$IFDEF IOS}
  c := 'ios';
  {$ENDIF}
  {$IFNDEF IOS}
  c := 'macos';
  {$ENDIF}
  {$ENDIF}
  {$IFDEF ANDROID}
  c := 'android';
  {$ENDIF}
  ExecuteJavascript('HandShake("'+c+'");');
end;
Sending and receiving messages
When the handshake is complete, the client can send and receive messages. The communication format is a JSON string that is automatically URL encoded and parsed to a JSON object. A sample sending from the client to the TMS WEB Core application:
procedure TForm1.ClientSendButtonClick(Sender: TObject);
var
  c: TJSONObject;
begin
  c := TJSONObject.Create;
  c.AddPair('Message From Client', 'Hello World !');
  w.Send(c);
  c.Free;
end;
And of course, sending back from a TMS WEB Core Application to the client:
procedure TForm1.WebButton1Click(Sender: TObject);
var
  o: TJSONObject;
  js: TJSON;
  s: string;
begin
  js := TJSON.Create;
  s := '{"Message From TMS WEB Core Application":"'Hello World !"}';
  o := js.parse(s);
  w.Send(o);
  o.Free;
end;
The future
This technology opens up a lot of possibilities for the future. You can send and receive messages with plain text, as well as small binary data encoded inside a JSON string between the client and the TMS WEB Core Application. The client application can then interact with the operating system, such as opening files, and other operating system specific functionality. The code runs on FMX (Windows, macOS, iOS, Android) and VCL (Windows) and is coming to TMS WEB Core in the near future!


Pieter Scheldeman




This blog post has received 6 comments.


1. Wednesday, October 24, 2018 at 11:24:51 AM

with this solution we could have Push Notification for Desktop App(?)

Flavio Basile


2. Wednesday, October 24, 2018 at 12:31:44 PM

If you''d route the incoming message from TMS WEB Core web client application in hosting app to the Windows (or other OS) notifications, this could indeed be a possible way.

Bruno Fierens


3. Friday, October 26, 2018 at 10:24:33 PM

Hello,

Great!!!

How fast is the process?.

Is there any plan to make the communication process synchronous?. For example, It would be desirable to have the feature from the TMS Web Core application to request to the FMXhave a response synchronous to be able to respond

Thank you and regards.

Conde Cantero Manuel Alonso


4. Friday, October 26, 2018 at 10:41:27 PM

Sorry, I submitted without finishing the question.

I was saying that it would be desirable to have the TMS Web Core application to request synchronously to the FMX application to be able to respond to calls from different parts of the TMS Web Core application without doing the process very complex. For example, if I have a TWebStringList.LoadFromFile procedure and my code call it, I want not to have to provide a parameter with a callback function to the procedure to get the response in the callback function because the communication with the FMX application is asychronous. This make the code complex, because of that I was asking if there are any plans to make the communication process synchronous. Sorry for the long explanation.

Thank you and regards.

Conde Cantero Manuel Alonso


5. Tuesday, October 30, 2018 at 12:29:36 PM

I''m not sure how this question relates to the bridge technology. When you send data from the hosting application to the TMS WEB Core application in the browser, an event is triggered in the TMS WEB Core web client application and vice versa. It could enable loading local files into the TMS WEB Core web client applications. The web client application will get the file data via an event, possibly in response to a call to the hosting desktop application. But here, this will be routed via an event and not as a result of a synchronous call.

Bruno Fierens


6. Tuesday, October 30, 2018 at 11:46:42 PM

Hello,

I was thinking by your blog that the communication is asynchronous ( event oriented ), becouse of that I was asking if there is any way to convert it in synchronous without the UI freeze during the moment that the response arrives. I want to call to the method LoadFromFile from the TMS Web Core application and that this make a request to the FMX application and the response will be received by a event, I know, but can I do to wait for the response?. A promise for example?, because I do not want that the code exit from the LoadFromFile until de response be received.

Thank you and regards.

Manuel




Add a new comment

You will receive a confirmation mail with a link to validate your comment, please use a valid email address.
All fields are required.



All Blog Posts  |  Next Post  |  Previous Post