STOMP Websocket synchronous communication using Spring - java

I have a requirement were some of the STOMP websocket connections needs to be handled synchronously.
Meaning I have a client (spring) subscribed to a topic ("/topic").
I have a server (spring) that has defined the broker ("/topic") also defined handlers ("/app/hello").
Now is it possible for the client to send a request to /app/hello and then wait for a response before sending the next request to /app/hello.
How do I return value on my sever (STOMP spec says about RECEIPT frames but I don't think this is something that can be manually controlled).
How do I wait for the value on my client after a send.

To connect a Java client to a websocket endpoint you can use the tyrus reference implementation of JSR356 - Websockets For Java.
Basically you will need to implement a client endpoint (javax.websocket.Endpoint) and a message handler (javax.websocket.MessageHandler). In the endpoint you register the message handler with the current session on open:
public class ClientEndpoint extends Endpoint {
...
#Override
public void onOpen(final Session aSession, final EndpointConfig aConfig) {
aSession.addMessageHandler(yourMessageHandler);
}
}
To connect to the server endpoint you can use the ClientManager:
final ClientManager clientManager = ClientManager.createClient();
clientManager.connectToServer(clientEndpoint, config, uriToServerEndpoint);
The message handler's onMessage method will be invoked, if the server endpoint sends something to the topic.
Depending on your needs you can either choose to implement the mentioned interfaces or use the corresponding annotations.
UPDATE:
The STOMP website lists several implementations of the STOMP protocol. For Java there are Gozirra and Stampy. I have no experience with these frameworks but the examples are pretty straight forward.

Related

Which message communication pattern is used in generated Vertx Service Proxy classes?

can somebody please clarify which type of message communication patterns:
Point-To-Point
Request-Reply
Publish/Subscribe
... is used in GENERATED Vert.X Service Proxy classes for RESTful CRUD app (which has 4 HttpServerVerticles which communicates with DatabaseVerticle and those are deployed by MainVerticle)?
Thank you in advance.
I persume it's Request-Reply since it sends Http Request and recieves Http Response since in "Vert.x in action" it states (in Chapter 3.1.4):
If you need message consumers to get back to the entity that sent the event then go for request-reply.
Any help/advice is greatly appreciated.
TL;DR: Request-Reply
If you look in the docs for service proxy (https://vertx.io/docs/vertx-service-proxy/java/) you can see in the beginning that it saves you from doing the following "boiler-plate" code:
JsonObject message = new JsonObject();
message.put("collection", "mycollection")
.put("document", new JsonObject().put("name", "tim"));
DeliveryOptions options = new DeliveryOptions().addHeader("action", "save");
vertx.eventBus().request("database-service-address", message, options, res2 -> {
if (res2.succeeded()) {
// done
} else {
// failure
}
});
Also from the same link:
A service is described with a Java interface containing methods
following the async pattern. Under the hood, messages are sent on the event bus to invoke the service and get the response back. But for
ease of use, it generates a proxy that you can invoke directly (using
the API from the service interface).

Two-way communications (ask or tell)?

akka documentation for java says
http://doc.akka.io/docs/akka/2.4/java/camel.html#Consumer_timeout
Two-way communications between a Camel endpoint and an actor are initiated by sending the request message to the actor with the ask pattern and the actor replies to the endpoint when the response is ready.
And then
http://doc.akka.io/docs/akka/2.4/java/camel.html#Asynchronous_routing
A consumer endpoint sends request messages to its consumer actor using the tell method and the actor returns responses with getSender().tell once they are ready.
Which of both statements is true?
Does it depend on the Camel component?
If tell method is used, how does the endpoint know to which client respond?
Thanks.

Ignoring HTTP response for web service one-way operation

I am developing a jax-ws webservice that pushes messages asynchronously to the subscribed consumers using one-way operation.
Unfortunatelly with each notification, server awaits a HTTP202 response confirmation which blocks the thread for a fraction of a second. This is affecting the performance of the system and I am looking for a way around this.
Is there any way to execute a web-service one-way call and ignore the HTTP response status?
Ok, so after spending a lot of time on this I have found two solutions:
1) Using Apache HTTPComponents, which provide AsyncHTTPClient with nice API allowing us to build a HTTP response from the scratch.
2) More web-service oriented solution based on Apache CXF platform (which includes the HTTPClient implementation) - first we need to set the global Bus property:
Bus bus = BusFactory.getDefaultBus();
bus.setProperty(AsyncHTTPConduit.USE_ASYNC, Boolean.TRUE);
Then, we use custom interceptor to set the message exchange property to asynchronous:
final class SkipWaitInterceptor extends AbstractSoapInterceptor {
SkipWaitInterceptor() {
super(Phase.SETUP);
}
#Override
public void handleMessage(final SoapMessage message) throws Fault {
message.getExchange().setSynchronous(false);
}
}
Finally, we register the interceptor on our asynchronous Endpoint
org.apache.cxf.endpoint.Client client =
org.apache.cxf.frontend.ClientProxy.getClient(this.notificationConsumer);
org.apache.cxf.endpoint.Endpoint cxfEndpoint = client.getEndpoint();
cxfEndpoint.getOutInterceptors().add(new SkipWaitInterceptor());
That's all, one-way operation responses no longer block the communication.

Push Message from ActiveMQ to Spring Controller

I'm using Spring MVC, ActiveMQ and WebSocket(via sock.js and stomp.js) to build a real-time data delivery application.
As we know, when a producer(another desktop application) push a message to ActiveMQ, and the onMessage() method will catch it.
public class MessageReceiver implements MessageListener {
public void onMessage(Message message) {
System.out.println(message);
// How to push the message to a Controller in Spring?
}
}
Most of the tutorials just print the message to the console.
I have another controller called WebSocketController:
#Controller
public class WebSocketController {
#SubscribeMapping("/getRealTimeResult.action/{submissionId}")
public Message getRealTimeResultAction(
#DestinationVariable long submissionId) {
return new Message("Message content from onMessage() method");
}
}
I want to push the message received in onMessage() method to the getRealTimeResultAction() method. Can you tell me how to do it?
I know that the ActiveMQ can communicate with the browser using stomp via the port 61613.
I don't want to do this because I think the MQ should be transparent to the user. Also I need to do some authorization in the WebSocketController.
Generally speaking an #Controller with #SubscribeMapping and #MessageMapping methods can handle subscriptions and messages from STOMP clients connected over WebSocket.
From your description it's not clear what you're trying to do. Was the message pushed to ActiveMQ via STOMP from a browser client or was it produced by some other back-end JMS client? Also the MessageReceiver receives an actual message while the #Controller method has an #SubscribeMapping method for handling a subscription from a STOMP client. It's not clear what you're trying to do. Please provide more information so I can provide a better answer.

Session Identification in Tyrus WebSocket API

I have implemented a websocket server which acts as observer for some events.
#ServerEndPoint
public class Server implements SomeObserver
I have implemented objectChanged() from SomeObserver class. The objectChanged() will execute when there is some event will be occur. It is common observer implemnetation.
The application logic is like this:
Clients connect to Websocket server and server sends appropriate events for appropriate clients.
I have coded it like this:
#ServerEndPoint
public class Server implements SomeObserver
{
Session clientSession = null;
#OnOpen
public void OnOpen(Session session}
{
clientSession = session;
}
//implemented OnMessage and OnClose, OnError methods
public void objectChanged(Event[] event)
{
clientSession.sendAsyncRemote().sendObject(someObjectInfo);
}
I never used any session identification. But surprisingly, server sends appropriate messages for respective session. Server does not send one sessions event to another session without any session authentication or identification.
Does anyone know why and how it happens in Tyrus API.
I want to know how Tyrus webocket support session identification.
clientSession.sendAsyncRemote().sendObject(someObjectInfo);
In the above line, the session object will be created per connection basis. It holds the reference socket object (per connection).
Hence, when message is sent, data will be transferred to the respective client.

Categories