GWT - Difference between (client --> server --> client) and (server --> client) communication - gwt

In my MVP app i have lots of (client --> server --> client) communication using GWT-RPC. The structure is straight forward, here's an example of a client call.
testObject.callToServer(example, new AsyncCallback<Void>(){
#Override
public void onFailure(Throwable caught) {
//handle failure
}
#Override
public void onSuccess(Object result)
//handle success
}
});
My question is, how would i implement server to client communication only, without the initial call from the client? Can i still use RPC, and if so can i reuse the code example above somehow?
Some more information, i'm using WebSockets to maintain an open communication link between client/server. I'm trying to figure out how to send more than just strings over the wire. I recognize the fact that RPC and Websockets are 2 different kinds of communication, and they may be mutually exclusive within a single communication instance.
As for what kind of data I want to be sending, right now just simple POJOs.
Thanks.

All methods of communicating with the server are 'just strings over the wire' - the difference with RPC is that it is a specially formatted string that describes the type, structure, and content of the objects being sent. The structures are predefined before the conversation even starts - in .class files for the server, and compiled into the JS format for the GWT code. There is a shared .gwt.rpc file in your app that then describes which types can be used in each pair of RPC interfaces, so that both sides can be sure that they know what the other side knows (specifically, the client names that file in each request, and the server agrees to use that file if it can be found, or else throw an error that the two are out of sync).
Putting objects into some other form of transport like websockets requires serializing objects into that string, and on the other side reading them out. To properly use RPC with the limitations it is designed to work with, you have to start the expected 'handshake', but since websockets starts from the client, this should be easily done.
In your self-answer, you mentioned that you switched to AutoBeans instead, letting you simply define very simple bean-like structures in interfaces, and be able to easily map them to JSON strings and back again. I've also done two simple implementations on the server of WebSockets plus RPC, with a single shared client impl: https://github.com/niloc132/webbit-gwt. This project support either JavaEE websockets, or Webbit (a websocket library that uses Netty). It isn't complete or bug-free, but lets you behave as if either side (server or client) can call the other freely, invoking methods with RPC-able objects, and provides some simple hooks for starting/stopping the socket.

I achieved this with GWT's Autobean framework.

Related

Mapping models from client and server Rest API

I am doing in a project using client-server communication through rest API, Angular 2 calling restful web service, for specific.
On client side, it is written in Typescript, a sub set of javascript.
My problem is our object on the server side is nested, complex and difficult to model/ deserialize exactly on the client side when it receives a response (JSON object)
My question is:
Do we need to make a class on the client side for all json
response object and deserialize them before binding it to the HTML
view or processing data?
And how big/complex could the response JSON object become a problem?
(Performance, Best practices...)
I am still confusing on how to share workload between client and server. What decides "we should handle it on server side" or "we should let the client do this"? Many of the cases I could let the server side fetch a lot of data before returning to clients, or should I let the client make multiple requests and fetch it on its side?
My application is probably an intranet application for ~ 1000 users (about 5-10 concurrently).
I am new to web application using rest, so I am greatly thank you if you guys could instruct me on this.
Let me answer to subquestion #3. I develop microservice architecture for a small project and have faced the same problem. It's possible to implement logic either at server side or at client side.
At one hand server could return simple plain objects, at another - could return objects containing all necessary nested and processed data.
In the first case, client should make more queries to the server in order to collect all nested data. The client should be more complex and foresee all the situations when server data could be changed during series of requests (keeping the consistency of data). But it really simplifies the server implementation - it could be just series of CRUD repositories. It could be even auto generated server over underlying DB.
In the second case, server returns complex nested object. It allows to simplify client, since JSON deserialization is pretty straightforward with modern frameworks. It reduces number of queries to server. If a client could have all the necessary data in one query - that's great.
In both cases the business logic should be implemented somewhere. I vote for the simple client and hiding complexity at server side. Finally, for one server could be several clients. That's why complex server will be more beneficial than complex client.

How can the Racket web server be used without managing continuations?

I am trying to develop a simple web API for testing using Racket's web server. The requirements are:
Respond to port requests with a callback in a new thread.
Read the header values and POST data
Write response headers and content to the port.
I do not want to engage the complexity of stateful versus stateless servlets. Essentially I want to avoid the overhead of managing continuations.
By avoiding calls to any send/... function other than send/back the serve/servlet can be used without invoking continuation handling.
Calling (serve/servlet start #:manager web-server/managers/non ...) will cause an error if there is an attempt to use continuations.
Custom headers/content can be created using a "raw" response structure.
Alternatively, using serve\launch\wait with a dispatcher using web-server/dispatchers/dispatch-lift is possible. Raw data may even be written directly to the port.
Reference: Original discussion on Racket discussion list.

GWT RequestFactory and propagating server-side changes to the client

I need some advice on how propagating server-side changes of entities to the client is best handled with GWT's RequestFactory.
Let us assume we have two EntityProxies, a PersonProxy and a PersonListProxy (which has a getter for a List). Assume that the client has fetched a PersonList and a Person from the server.
In case the client is editing one of these proxies and firing a request, the machinery of RequestFactory (if I have understood the principles correctly) will fire an EntityProxyChange event if it detects changes done by server code (so that the client can update its display of the entities, for example).
Now assume that the server is changing its entities outside of a request by this client (e.g. due to another client calling the server) so that this client would see another version if it fetched the Person or the PersonList again.
My question is what is the best way inside the RequestFactory framework to tell the client of the changes (and to reuse as much of the machinery as possible)? We can assume that I have a way to send simple messages from the server to the client (e.g. Google App Engine's channel API or server-sent events).
One idea could be that the server sends over this channel a message telling that a Person or a PersonList with a specific id has changed. The client code handling the receipt of these messages could then use RequestFactory to re-fetch (e.g. find) the entity. This change should then be propagated to other parts of the client by an EntityProxyChange event.
Is this the way to go? (And in case that the client already has the current version of the entity, e.g. because the server was dumb and notified the client of changes the client itself made, would the triggered re-fetch just transport a few bits of metadata and not the whole entity again?)
ADDED:
Thinking a bit more about it, I wonder how EntityProxyId's can be generated for the server-sent event channel. When an entity on the server changes, the server only has the server id. It can then send it to the client, of course, but the client only knows of EntityProxyId's. Of course, I could add a getId() (in addition to getStableId()) to each EntityProxy, but it looks as if this would add redundant data to every server response.
Well, I realize that my post isn't precise answer to your question, but it's just my experience.
In fact, there is just a question how to deliver data from server to client.
I faced with some task couple years ago, and found for yourself an approach that make my life easier. To explain it, I want to specify my reasons:
You have to have full data delivery by requesting it from client - it's straight, natural way to requesting data;
You don't want to create and support 2 different models of full data delivery: one by requesting from client and second by pushing from server;
But you need to inform client about some changes on server side;
So, now I'm building my architecture using following approach:
Build full classical client-server API for data delivery - so you can load and refresh your application in natural way even if your pushing functionality is blocked or broken.
Define key information that may be changed on server side and should be delivered to client via push mechanism.
Create small push message construct(s) that will deliver to client just a notification about changes - no any valuable data should be delivered this way - just keys which data was changed.
All that is needed to do on client when it receives such notification is just to get/refresh data from server in natural client-server way that is already supported.
Server logic shouldn't bother client side by huge amount of notifications - sometimes is more effective do not deliver changes, but just refresh everything.
Hope this helps.

GWT RPC -- Effect of sending very large binary data?

Assuming a standard Jetty servlet container, what is the effect (On the server, or the client) of sending a large set of binary (string) data over RPC?
Specifically, since it does not seem that GWT RPC has support for streaming, I am concerned that two things might happen:
Large memory consumption on the server side since the binary data is being loaded into memory of the RPC class.
Slow serialization or de-serialization.
Assuming any of these are true, what are my options? I am trying to build a uniform API so I'd rather not have to tell the developer: "Oh in this case, manually create a REST request to get the data".
If you need to transfer a really big amount of binary data, GWT-RPC is a bad choice (all the problem you've listed are correct ones). But if you want a uniform API on the client side, without telling the developer to simply use raw HTTP to get data, you'll have to provide client implementation for your binary service.

Decoding GWT RequestFactory payload without Request from out-of-bound message

We're using GWT Atmosphere to send strings from the server to the client and it works quite well.
However, we would like to send whole entities from the server to the client, serialized by the GWT RequestFactory. Without the need for a request by the client!
So I tried working with SimpleRequestProcessor#createOobMessage(domainObject) and sending that payload to the client. Computing the payload works.
I would then decode that message using AutoBeanCodex#decode and read the domainObject as the correct EntityProxy from the invocation list of the ResponseMessage - however when I do so, it requires some sort of serverId being set to proceed in AbstractRequestFactory#getId (around line 260: assert serverId != null : "serverId")
Any advice on how I can decode a Proxy payload without a request being sent by the client?
Update
The use case for this question is chat-like communication. The client doesn't request the messages from the server but instead will be notified of new messages. And we'd like to include the messages and info on who's sent the message in the notification payload. Since we're using RequestFactory in our project anyway, we want to take advantage of having set up all the Proxy wiring and now simply push the relevant object graph to the client.
Why are you trying to serialize RF messages and send them just as entities? RequestFactory is much more than justa way to send data over the wire - it has at least three different kinds of messages that can be sent from the client to the server: create instances, call setters, and invoke service methods. Based on what happens on the server, not only can data be returned to the client, but messages about what changes were made and if those setters made changes that are not valid under the JSR303 rules.
Are you trying for a simpler, interface way of describing, sending, and receiving entities? Or do you actually want the RF wiring on both client and server so you can batch requests, refer to EntityProxyId instances and have the client only send diffs?
If you just want simpler object declarations, try just using AutoBeans and the AutoBeadCodex you have already looked at - you'll be able to create and marshal instances on both client and server easily, and you can pass them as strings over atmosphere's transports.
If you actually want RequestFactory, but running over something other than AJAX, there are other options. Rather than sending/receiving strings through Atmosphere (which I believe is intended to provide push support for RPC calls), consider using that underlying push layer to implment a new request transport in RequestFactory.
com.google.web.bindery.requestfactory.shared.RequestTransport can be implemented (see com.google.web.bindery.requestfactory.gwt.client.DefaultRequestTransport for the default AJAX version) to use any communication mechanism you would like - and to build the server, take a look at com.google.web.bindery.requestfactory.server.RequestFactoryServlet for what actually must be done to push messages through the Locator, ServiceLocators, etc.
If you really want to use Atmosphere and RF, then consider building a RequestTransport that wraps a simple Atmosphere interface to call to the server with the string - the cometd/websocket calls will already be taken care of for you, and you'll just have to translate the string message into invocations (again, see how RequestFactoryServlet does it).