Connecting and sending message between Spring WebSocket instances - java

I have multiple instances using Spring Boot WebSocket (created following the first half of Spring's guide). I need them to connect to other instances at specific hostnames and ports and to be able to send messages over the websocket connection using STOMP protocol.
How can I connect to my other services over websocket?
How can I send messages using the STOMP protocol (preferably using the same marshalling/unmarshalling magic I get with received messages)?
Things that don't answer my question:
I have read Spring: send message to websocket clients and Sending message to specific user on Spring Websocket but these and other questions seem to all assume that a client has already initiated a connection and that there are users and topics established. This is not my use case as my services are both server AND client.
I am not using a cluster and I am not sharing sessions across instances as in Spring Websocket in a tomcat cluster

I have found some resources that cast some light on how to accomplish this:
http://www.baeldung.com/websockets-api-java-spring-client
https://www.sitepoint.com/implementing-spring-websocket-server-and-client/#javaspringchatclient
http://useof.org/java-open-source/org.springframework.messaging.simp.stomp.StompSessionHandler
number 3 is at least a complete implementation but is unfortunately devoid of comments to explain what's going on.

Related

Running TCP server in Java Spring/Springboot framework instead of http/https

I want to write a TCP/IP Socket based application using Java Spring/Spring Boot framework. However I am facing problem in bringing the TCP server up. Whenever I init the application it brings the tomcat up instead of my tcp server port. My requirement is that the my application will act as a TCP server/client based on the configuration and will connect/accept connection from Third Party. It shall process the requests and send responses back. The application needs to receive/send stream of bytes.
I tried googling a lot and found a few articles indicating implementing a CommandLineRunner interface of SpringBoot however that also did not work. Could you please assist on this

Micronaut, how to send updates to a websocket endpoint? (Java)

Currently I discover micronauts and regarding websockets, I am looking for a solution. Let me describe the idea and the issue:
A Browser connects to a microservice with a websocket endpoint
A session-ID may be send to the websocket endpoint to identify the client
On a different http request a long term async work has been started (e.g. with a message queue)
The process finishes and needs to tell the right websocket endpoint-thread to give this update to the browser.
But what would be a good way to tell the correct websocket thread, connected to the browser, an update is available?
What if there are more than one websocket microservices, called by a balancer? I think then they can not share any "Session" with an http server?
Can the exact websocket endpoint subscribe to a message service like Kafka?
I just found people asking the same with no answer. But it seems to be a typical issue.

Channel vs. Broker vs. Destination in Websocket

What is the difference between channel vs. broker vs. destination in Spring websocket?
I recently started working with a websocket and from what I understood:
registry.addEndpoint("/wsocket/") adds a websocket endpoint which is solely used when clients wants to connect to the websocket service:
this.client.configure({
brokerURL: `ws://localhost:9022/wsocket`,
onConnect: () => {
this.client.subscribe('/quote/fb', message => {
console.log(message);
});
}
});
this.client.activate();
config.enableSimpleBroker("/quote") enables a channel/broker, letting clients to subscribe to it and receive messages published/sent over it. Clients are able to subscribe to any /quote/* on the server.
config.setApplicationDestinationPrefixes("/app") sets the application prefix, which clients use to send message directly to the app and not through the broker.
Is my understanding correct?
I think your understanding is correct .
Broker
A message broker acts as an intermediary platform when it comes to processing communication between two applications. In the context of spring websocket :
When you use Spring’s STOMP support, the Spring WebSocket application acts as the STOMP broker to clients. Messages are routed to #Controller message-handling methods or to a simple in-memory broker that keeps track of subscriptions and broadcasts messages to subscribed users. You can also configure Spring to work with a dedicated STOMP broker (such as RabbitMQ, ActiveMQ, and others) for the actual broadcasting of messages. In that case, Spring maintains TCP connections to the broker, relays messages to it, and passes messages from it down to connected WebSocket clients.
Channel
It can be thought of as a logical segregation of messages in one or both directions. For example, there can be three channels. One for request(incoming to the server), second one for response(outgoing from the server) and third one for error (outgoing from the server).
Destination
It can be thought of another level of hierarchical nesting for a channel. I find this image helpful to understand it :
https://docs.spring.io/spring/docs/5.1.3.BUILD-SNAPSHOT/spring-framework-reference/images/message-flow-simple-broker.png
[![enter image description here][1]][1]
Clients can use the SEND or SUBSCRIBE commands to send or subscribe for messages, along with a destination header that describes what the message is about and who should receive it. This enables a simple publish-subscribe mechanism that you can use to send messages through the broker to other connected clients or to send messages to the server to request that some work be performed.
I find Spring documentation on this topic to be very helpful : https://docs.spring.io/spring/docs/5.1.3.BUILD-SNAPSHOT/spring-framework-reference/web.html#websocket-stomp-handle-simple-broker .

Configuration for Spring stomp multi-application server

I'm developing a realtime notification system in Spring 4 by using a build-in Message Broker, and STOMP over WebSocket.
I would like to handle a case when there is a multi-application server and user destination is unresolved (because user is connected to another server). Spring docs claim there is a solution:
In a multi-application server scenario a user destination may remain
unresolved because the user is connected to a different server. In
such cases you can configure a destination to broadcast unresolved
messages to so that other servers have a chance to try. This can be
done through the userDestinationBroadcast property of the
MessageBrokerRegistry in Java config and the
user-destination-broadcast attribute of the message-broker element in
XML.
But there is no example of such configuration. How can I set servers to recieve these messages and authentification parameters for system channel?
When dealing with multi-node applications using WebSockets over STOMP you must configure and use an external STOMP Broker (such as RabbitMQ) so that different application instances can communicate each other. Are you already doing it, right?
In order to configure the userDestinationBroadcast and the userRegistryBroadcast just assign a destination name to them. When the application starts and the system TCP connection between the app and the broker is established, these destinations will be automatically created and everything will work fine and transparently.
I've coded a Web Chat app using Spring WebSockets, RabbitMQ and much more and its configuration is available here.
I hope this helps.

Asynchronous communication with JMS

We are using in some project WebSockets for asynchronous communication between Java client and Java server, but we have to replace it with something less modern (we cannot use Websphere liberty profile and it must run on Websphere). Connection can be made only form client to server, not reversely and it should be HTTP(s) as it has to traverse a reverse proxy. Is it possible to use JMS to push messages to client in this situation? (we tried atmosphere-wasync as well but rejected it due to instability).

Categories