Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Remote Application Platform (RAP) » Calling a client service from RAP
Calling a client service from RAP [message #1172098] Tue, 05 November 2013 12:55 Go to next message
Vincenzo Caselli is currently offline Vincenzo Caselli
Messages: 100
Registered: January 2012
Senior Member
Hi all,
we would like to call a local service running on the client machine from RAP.
This could be any kind of Java service; we are open to many options (REST, JSON, MQTT, ...).
In the end the goal is to be able to interact with a local scanner managed by a local Java application, but the same could apply for, let's say, a 'dir' command on the local 'C:' disk.
What could be the best and direct way to accompish this task with RAP?
Thank you very much.

Vincenzo
Re: Calling a client service from RAP [message #1176328 is a reply to message #1172098] Fri, 08 November 2013 04:07 Go to previous messageGo to next message
Ralf Sternberg is currently offline Ralf Sternberg
Messages: 1290
Registered: July 2009
Senior Member

Hi Vincenzo,

JavaScript code runs in a sandbox to prevent access to local services
from a web page. There may be some tricks to circumvent this, but since
this restriction is there for a good reason (you don't want a webpage to
do anything on your system), any approach that tries to break out of the
browser sandbox feels like a hack to me.

I'm not sure if a custom browser plug-in could help to provide a
JavaScript interface for your local services.

But instead of thinking about a local communication channel on the
client, what about providing a custom servlet on the RAP server that the
client-side Java applications can connect to?
Your RAP application could "push" jobs to these local applications and
receive results.

I'm not sure if this applies to your problem, but there are USB scanners
that work like a keyboard and can directly write into a hidden text field.

HTH,
Ralf

--
Ralf Sternberg

Twitter: @EclipseRAP
Blog: http://eclipsesource.com/blogs/

Professional services for RAP and RCP?
http://eclipsesource.com/services/rap/
Re: Calling a client service from RAP [message #1176697 is a reply to message #1172098] Fri, 08 November 2013 08:51 Go to previous messageGo to next message
Ivan Furnadjiev is currently offline Ivan Furnadjiev
Messages: 1794
Registered: July 2009
Senior Member
Hi Vincenzo,
one possible solution will be a signed Java applet running in the same
page with your RAP application. Every modern browser support
Java-to-JavaScript bridge. With signed Java applet you will overcome to
browser sandbox.
HTH,
Ivan

On 11/5/2013 7:55 PM, Vincenzo Caselli wrote:
> Hi all,
> we would like to call a local service running on the client machine
> from RAP.
> This could be any kind of Java service; we are open to many options
> (REST, JSON, MQTT, ...).
> In the end the goal is to be able to interact with a local scanner
> managed by a local Java application, but the same could apply for,
> let's say, a 'dir' command on the local 'C:' disk.
> What could be the best and direct way to accompish this task with RAP?
> Thank you very much.
>
> Vincenzo

--
Ivan Furnadjiev

Twitter: @EclipseRAP
Blog: http://eclipsesource.com/blogs/

Professional services for RAP and RCP?
http://eclipsesource.com/services/rap/
Re: Calling a client service from RAP [message #1177343 is a reply to message #1172098] Fri, 08 November 2013 18:17 Go to previous messageGo to next message
Vincenzo Caselli is currently offline Vincenzo Caselli
Messages: 100
Registered: January 2012
Senior Member
Ralf, Ivan,
thank you!

@Ralf
we have to do a RAP porting of a quite complex RCP application that uses not only different kind of scanners, but also other local devices, so a direct communication between the browser and the local JVM is strongly needed. I agree on the fact that the javascript sandbox (it would be the same for an applet) is there for a reason, but a security mechanism can be always set up, considered that it would be an intranet webapp.

@Ivan
the signed applet solution was our first thought, but there are a number of reason against this (sounds like an old way, applets has gained a bad name in years, Oracle latest updates seems to be more restrictive about them, ...)

Anyway in the meantime we had some success with a local REST+JSONP service called by a standard (not RAP) webapp using jQuery.
I've read that RAP has jQuery integration, so this may be a good solution.
Can you point me out of some simple example of how to use jQuery in RAP?
I was looking at org.eclipse.rap.demo.carousel and org.eclipse.rap.widget.carousel example, but if there is a simpler "how-to" on this, please let me know.

Thank you again
Vincenzo
Re: Calling a client service from RAP [message #1181099 is a reply to message #1177343] Mon, 11 November 2013 06:19 Go to previous messageGo to next message
Ralf Sternberg is currently offline Ralf Sternberg
Messages: 1290
Registered: July 2009
Senior Member

Hi Vincenzo,

I see. There is no explicit JQuery integration in RAP, but we made sure
that RAP's JS library does not interfere with JQuery. To use JQuery with
RAP, you first need to load the JQuery library. You can use the
JavaScriptLoader service to do so:

JavaScriptLoader loader
= RWT.getClient().getService( JavaScriptLoader.class );
loader.require( "http://code.jquery.com/jquery-1.9.0.min.js" );

To execute some custom JavaScript code on the client, use the
JavaScriptExecutor service:

JavaScriptExecutor executor
= RWT.getClient().getService( JavaScriptExecutor.class );
executor.execute( "console.log( $('body') );" );

Hope this helps.
Ralf

--
Ralf Sternberg

Twitter: @EclipseRAP
Blog: http://eclipsesource.com/blogs/

Professional services for RAP and RCP?
http://eclipsesource.com/services/rap/
Re: Calling a client service from RAP [message #1181982 is a reply to message #1181099] Mon, 11 November 2013 19:07 Go to previous messageGo to next message
Vincenzo Caselli is currently offline Vincenzo Caselli
Messages: 100
Registered: January 2012
Senior Member
Hi Ralf,
thank you!
It works! But we had to do something more: let me explain.
Our goal is to achieve this communication schema:
RAP -> JS -> REST/JSONP -> JS -> RAP

but the following call
JavaScriptExecutor executor = ...
executor.execute();


returns void, so at first we had a problem while trying to pass data from Javascript back to RAP/Java.

Looking around for a solution we found how to do it basically in this way:

  ResourceUtil.registerIfAbsent(Activator.class.getClassLoader(), "resources/jquery-1.7.1.min.js");
  String url = ResourceUtil.registerIfAbsent(Activator.class.getClassLoader(), "resources/browserFunctionTest.html");
  final Browser browser = new Browser(parent, SWT.NONE);
  new BrowserFunction(browser, "javaFunction") {
          @Override
          public Object function(Object[] arguments) {
              //This function is called by JS, which passes its data here back to RAP
              ...
              return "from Java to JS again (not used)";
          }
      };
      browser.setUrl(url);


And so in the end the communication cycle is complete!

We just wonder if this is the simplest solution. Would it be possible to do without the Browser and have a sort of callback from JavaScriptExecutor ?

Re: Calling a client service from RAP [message #1182635 is a reply to message #1181982] Tue, 12 November 2013 05:03 Go to previous messageGo to next message
Tim Buschtoens is currently offline Tim Buschtoens
Messages: 382
Registered: July 2009
Senior Member
Hi.

>
> We just wonder if this is the simplest solution. Would it be possible to
> do without the Browser and have a sort of callback from
> JavaScriptExecutor ?
>

That is possible, though it's a some work and requires some advanced
JavaScript and RAP knowledge. I wouldn't call it "simpler", only more
elegant.

I thought a few times before about implementing something like a
"ServerFunction", basically a BrowserFunction without the Browser
widget, but never got around to it. This could be implemented using the
Client/Server Remote APIs, like a custom widget, but with no widget.
It's not a polished idea, but here is the rough outline:

- Implement an abstract Java class ServerFunction that has a single
abstract callback method "execute" (like a runnable).
- In the constructor of the class create a RemoteObject[1] of the type
"ServerFunction" and add an OperationHandler[2] that calls the "execute"
method for call operations "execute"[3]. The properties map could be
passed on as-is or converted in some manner to suit your needs.
- On the client you need to register an TypeHandler[4] for
"ServerFunction" that in the factory returns a function that gets it's
own client-side remoteObject[5]. (To do so the function body needs to
reference itself, which may be tricky but possible, e.g. using named
functions or the arguments object.)
- On the remoteObject the function calls "call"[6] and passes on it's
parameter(s) in a remote-API compliant format.
- Lastly, to be able to call the ServerFunction on the client you need
to be able to reference it. I'm not yet sure what the best solution for
that would be. You could either expose the remoteObjects id on the
server-side ServerFunction[7][8], or you could give the function a name
in the constructor and add the function to the global namespace using
that name in the typeHandler, much like the BrowserFunction in the
Browsers loaded document.

I can't really go into much more detail without trying it out for
myself. If your method works for you that is fine too I guess.

Greetings,
Tim

[1]
http://download.eclipse.org/rt/rap/doc/2.2/guide/reference/api/org/eclipse/rap/rwt/remote/Connection.html#createRemoteObject%28java.lang.String%29
[2]
http://download.eclipse.org/rt/rap/doc/2.2/guide/reference/api/org/eclipse/rap/rwt/remote/RemoteObject.html#setHandler%28org.eclipse.rap.rwt.remote.OperationHandler%29
[3]
http://download.eclipse.org/rt/rap/doc/2.2/guide/reference/api/org/eclipse/rap/rwt/remote/OperationHandler.html#handleCall%28java.lang.String,%20org.eclipse.rap.json.JsonObject%29
[4]
http://download.eclipse.org/rt/rap/doc/2.2/guide/reference/jsdoc/symbols/rap.html#.registerTypeHandler
[5]
http://download.eclipse.org/rt/rap/doc/2.2/guide/reference/jsdoc/symbols/rap.html#.getRemoteObject
[6]
http://download.eclipse.org/rt/rap/doc/2.2/guide/reference/jsdoc/symbols/RemoteObject.html#call
[7]
http://download.eclipse.org/rt/rap/doc/2.2/guide/reference/api/org/eclipse/rap/rwt/remote/RemoteObject.html#getId%28%29
[8]
http://download.eclipse.org/rt/rap/doc/2.2/guide/reference/jsdoc/symbols/rap.html#.getObject
--
Tim Buschtöns

Twitter: @EclipseRAP
Blog: http://eclipsesource.com/blogs/

Professional services for RAP and RCP?
http://eclipsesource.com/services/rap/
Re: Calling a client service from RAP [message #1184202 is a reply to message #1182635] Wed, 13 November 2013 04:40 Go to previous message
Vincenzo Caselli is currently offline Vincenzo Caselli
Messages: 100
Registered: January 2012
Senior Member
Hi Tim,
thank you for your detailed answer!
Probably I would have some difficulty in the implementation by myself.
Anyway for now the Browser way seems to work well, especially now that I found this post
http://www.eclipse.org/forums/index.php/mv/msg/490122/1067905/#msg_1067905
in which you suggest to use
window.setTimeout( callTheJavaFunction, 0 );

well Tim, you saved my day!
Thank you very much.
Cheers

Vincenzo
Previous Topic:Client Error "a is undefined" on asynchronous UI update
Next Topic:Support RAP 1.5
Goto Forum:
  


Current Time: Thu Aug 28 01:13:59 EDT 2014

Powered by FUDForum. Page generated in 0.29786 seconds