Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Remote Application Platform (RAP) » Custom Component: Server Side Component
Custom Component: Server Side Component [message #1234149] Tue, 21 January 2014 10:47 Go to next message
Tobias P. is currently offline Tobias P.
Messages: 43
Registered: April 2012
Member
Hello,

as mentioned in the other topic (http://www.eclipse.org/forums/index.php/t/637543/) i am trying to create a custom component based on Javascript Jit Visualization.

Right now, i am struggeling with the Java Server side implementation.

In the client i am doing the following:

// This method is called on DOM label creation.
// Use this method to add event handlers and styles to
// your node.
onCreateLabel : function(label, node) {
label.id = node.id;
label.innerHTML = node.name;
label.onclick = function() {
console.log("clicked " + node.name);
remoteObject.onSend(node);
};

//later
onSend : function(node) {
   if (typeof (node) != "undefined") {
       console.log(node);
       rap.getRemoteObject(this).set("text", node.name);			}
	},


I want to achieve the following:

I am displaying a tree with different nodes, and when a node is clicked, the name should be send to the server, do a server side operation, and send the result back to client.

On the Server, i am doing the following which is based on the CKEditor template:

private final OperationHandler operationHandler = new AbstractOperationHandler() {
		@Override
		public void handleSet(JsonObject properties) {
			JsonValue textValue = properties.get("text");
			if (textValue != null) {
				text = textValue.asString();
				System.out.println(text);
			}
		}
	};


Whenever i click a node on the client, nothing happens until i resize the client window. Then the System.out.println on the server is called.

I searched around the wiki and the forum and found the following:

call(method, properties)
Instructs the remote object to call the given method. Calling this method will write a "call" operation into the message, which will to be sent to the server within a few milliseconds. One message may contain several "call" operations, if they are added consecutively.
Parameters:
{string} method
The name of the method.
{Object|null} properties Optional
This object may contain any number of additional properties/fields associated with the call. It may also be null or omitted.


So when i change the client code to the following:

onSend : function(node) {
			if (typeof (node) != "undefined") {
				console.log(node);
				rap.getRemoteObject(this).call("text", node.name);
			}
		},


I get the following error
WARN  qtp1306210867-85             org.eclipse.jetty.servlet.ServletHandler                          /daios/app org.eclipse.rap.json.ParseException: Unexpected end of input at 1:-1
	at org.eclipse.rap.json.JsonParser.error(JsonParser.java:371)
	at org.eclipse.rap.json.JsonParser.expected(JsonParser.java:362)
	at org.eclipse.rap.json.JsonParser.readValue(JsonParser.java:97)
	at org.eclipse.rap.json.JsonParser.parse(JsonParser.java:62)
	at org.eclipse.rap.json.JsonValue.readFrom(JsonValue.java:92)
	at org.eclipse.rap.json.JsonObject.readFrom(JsonObject.java:123)
	at org.eclipse.rap.rwt.internal.protocol.ProtocolUtil.getClientMessage(ProtocolUtil.java:69)
	at org.eclipse.rap.rwt.internal.service.LifeCycleServiceHandler.isSessionShutdown(LifeCycleServiceHandler.java:241)
	at org.eclipse.rap.rwt.internal.service.LifeCycleServiceHandler.synchronizedService(LifeCycleServiceHandler.java:78)
	at org.eclipse.rap.rwt.internal.service.LifeCycleServiceHandler.service(LifeCycleServiceHandler.java:67)
	at org.eclipse.rap.rwt.engine.RWTServlet.handleValidRequest(RWTServlet.java:121)
	at org.eclipse.rap.rwt.engine.RWTServlet.handleRequest(RWTServlet.java:108)
	at org.eclipse.rap.rwt.engine.RWTServlet.doPost(RWTServlet.java:99)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:755)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
	at org.eclipse.rap.rwt.osgi.internal.CutOffContextPathWrapper.service(CutOffContextPathWrapper.java:106)
	at org.eclipse.equinox.http.servlet.internal.ServletRegistration.service(ServletRegistration.java:61)
	at org.eclipse.equinox.http.servlet.internal.ProxyServlet.processAlias(ProxyServlet.java:128)
	at org.eclipse.equinox.http.servlet.internal.ProxyServlet.service(ProxyServlet.java:60)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
	at org.eclipse.equinox.http.jetty.internal.HttpServerManager$InternalHttpServiceServlet.service(HttpServerManager.java:386)
	at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:669)
	at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:457)
	at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:229)
	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1075)
	at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:384)
	at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:193)
	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1009)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116)
	at org.eclipse.jetty.server.Server.handle(Server.java:368)
	at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:489)
	at org.eclipse.jetty.server.AbstractHttpConnection.content(AbstractHttpConnection.java:953)
	at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.content(AbstractHttpConnection.java:1014)
	at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:861)
	at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:240)
	at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82)
	at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:628)
	at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:52)
	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608)
	at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:543)
	at java.lang.Thread.run(Thread.java:744)


I even red the Wiki Page with title
How exactly do I use the "listen" method?

But i dont understand how to add the mentioned method.

To make a long story short, how can i achieve that the server responds a event of the client?

If you need further information please feel free to ask.
Tobias

Re: Custom Component: Server Side Component [message #1234308 is a reply to message #1234149] Tue, 21 January 2014 16:54 Go to previous messageGo to next message
Tim Buschtoens is currently offline Tim Buschtoens
Messages: 386
Registered: July 2009
Senior Member
Hello...

> // This method is called on DOM label creation.
> // Use this method to add event handlers and styles to
> // your node.
> onCreateLabel : function(label, node) {
> label.id = node.id;
> label.innerHTML = node.name;
> label.onclick = function() {
> console.log("clicked " + node.name);
> remoteObject.onSend(node);
> };

I don't know what "node" is or where you get the "remoteObject" from,
but if it is a normal RAP remoteObject this can't be right since there
is no "onSend" method on RemoteObject. If you created some object
yourself and called it "remoteObject" then I would rethink that name,
because anyone reading your code would be really confused about that.

>
> //later
> onSend : function(node) {
> if (typeof (node) != "undefined") {
> console.log(node);
> rap.getRemoteObject(this).set("text", node.name); }
> },

Assuming the "this" is correctly set and the method is called, this
looks correct.


> Whenever i click a node on the client, nothing happens until i resize
> the client window. Then the System.out.println on the server is called.

That is what the above code should do, yes. As the documentation states
"This method does not cause the message to be sent immediately. Instead
it will be sent the next time a "notify" or "call" operation is written
to the message."
(http://download.eclipse.org/rt/rap/doc/2.2/guide/reference/jsdoc/symbols/RemoteObject.html#set)
- In this case the window resize causes a notify operation somewhere
else entirely.

> So when i change the client code to the following:
>
> onSend : function(node) {
> if (typeof (node) != "undefined") {
> console.log(node);
> rap.getRemoteObject(this).call("text", node.name);
> }
> },
>
>
> I get the following error
> WARN qtp1306210867-85
> org.eclipse.jetty.servlet.ServletHandler
> /daios/app org.eclipse.rap.json.ParseException: Unexpected end of input

Yes, probably because "call" expects a property map as the second
parameter, not a string.
(http://download.eclipse.org/rt/rap/doc/2.2/guide/reference/jsdoc/symbols/RemoteObject.html#call)


In any case, "set" is the right method to use, not "call". But "set" is
only meant to synchronize client/server state, not to send events. So if
you want to notify your application that something happened, then in
ADDITION to "set" you need to send a "notify" operation. How this is
done is documented
here(http://download.eclipse.org/rt/rap/doc/2.2/guide/reference/jsdoc/symbols/RemoteObject.html#notify)
and
here("https://wiki.eclipse.org/RAP/Custom_Widgets_FAQ#How_exactly_do_I_use_the_.22listen.22_method.3F")

Example:
remoteObject.set( "text", "something" );
remoteObject.notify( "textChanged" );


As explained there, for your notify operation to work you need to have
the event type in the typeHandlers "events" array
(http://download.eclipse.org/rt/rap/doc/2.2/guide/reference/jsdoc/symbols/rap.html#.registerTypeHandler)
and render a "listen" operation form the server
(http://download.eclipse.org/rt/rap/doc/2.2/guide/reference/api/org/eclipse/rap/rwt/remote/RemoteObject.html#listen%28java.lang.String,%20boolean%29).
The idea is that a notify is only send if the server actually has to do
something for that event, usually notify listeners that execute
application code. If the application didn't register any listeners then
the client doesn't have to send notify operations, so it doesn't do that
and the "set" operation is send with the next request.

If you ALWAYS have to do something IMMEDIATELY on a client side event,
"call" would be the right operation to use. E.g.:

remoteObject.set( "text", "something" );
remoteOBject.call( "doSomething" );

However, that might be a sign of bad design. Why would the server side
widget have to immediately do something on a client side value change
unless there are listeners from the application?

If you don't understand something about this or have suggestions how to
make it more understandable in the wiki, let me know.

Greetings,
Tim

--
Tim Buschtöns

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

Professional services for RAP and RCP?
http://eclipsesource.com/services/rap/
Re: Custom Component: Server Side Component [message #1234993 is a reply to message #1234308] Thu, 23 January 2014 09:50 Go to previous messageGo to next message
Tobias P. is currently offline Tobias P.
Messages: 43
Registered: April 2012
Member
Hello Tim, first of all i got it working following http://archive.is/viFEL and with your further explantation.

Secondly, if i see my working example the RAP API is pretty simple and straightforward! Kudos to the team.

I will add a longer post later this day, what i did wrong and how i got it working.

Re: Custom Component: Server Side Component [message #1445308 is a reply to message #1234993] Wed, 15 October 2014 09:01 Go to previous message
Alex Sam is currently offline Alex Sam
Messages: 6
Registered: May 2014
Location: France
Junior Member
No Message Body

[Updated on: Wed, 15 October 2014 14:48]

Report message to a moderator

Previous Topic:How to set i18n for this message?
Next Topic:cell problem
Goto Forum:
  


Current Time: Thu Oct 23 20:51:59 GMT 2014

Powered by FUDForum. Page generated in 0.02167 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software