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 17:55 |
|
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 09:07 |
|
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 13:51 |
Ivan Furnadjiev Messages: 2427 Registered: July 2009 Location: Sofia, Bulgaria |
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 23:17 |
|
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 11:19 |
|
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] |
Tue, 12 November 2013 00:07 |
|
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 10:03 |
Tim Buschtoens Messages: 396 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/
|
|
| |
Goto Forum:
Current Time: Fri Sep 20 19:54:26 GMT 2024
Powered by FUDForum. Page generated in 0.04041 seconds
|