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.
Related
I'm trying to create an app with notification service whenever a call is made on API.
Is it possible for me to create a logger on port:8080 and when app is run on the server it listens to api running on another server.
Both applications are run on local machine for testing purposes using Docker.
So far I've been reading https://www.baeldung.com/spring-boot-logging in order to implement it but I'm having problems with understanding the path mapping.
Any ideas?
First let's name the two applications:
API - the API service that you want to monitor
Monitor - which wants to see what calls are made to (1)
There are several ways to achieve this.
a) Open up a socket on Monitor for inbound traffic. Communicate the IP address and socket port manually to the API server, have it open up the connection to the Monitor and send some packet of data down this "pipe". This is the lowest level approach simple, but very fragile as you have to coordinate the starting of the services, and decide on a "protocol" for how the applications exchange data.
b) REST: Create a RESTful controller on the Monitor app that accepts a POST. Communicate the IP address and port manually to the API server. Initiate a POST request to the Monitor app when needed. This is more robust but still suffers from needing careful starting of the servers
c) Message Queue. install a message queue system like RabbitMQ or ActiveMQ (available in Docker containers). API server publishes a message to a Queue. Monitor subscribes to the Queue. Must more robust, still requires each application to be advised of the address of the MQ server, but now you can stop/start the two applications in any order
d) The java logging article is good started into java logging. Most use cases log to a local file on the local server. There are some implementations of backend logging that send logs to remote places (I don't think that article covers them), and there are ways of adding your own custom receiver of this log traffic. In this option, on the API side, it would use ordinary logging code with no knowledge of the downstream consumption of the logging. Your monitor app would need to integrate tightly into a particular logging system with this approach.
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.
Is there any way to get notification from server whenever it is on?
my requirement is when ever ActiveMQ is on a piece of code will run automatically
in ActiveMQ is there is no load on startup
Create a publisher in your language of choice that periodically sends a test message to ActiveMQ.
Create a subscriber in your language of choice that receives the test messages and notifies you via your mechanism of choice that it has successfully received a test message.
The Apache ActiveMQ broker supports discovery with IP multicast.
Applications can use discovery for JMS clients to auto-detect a Message Broker to connect to.
This could also be used to monitor a broker's status, using Java MultiCast support.
To invoke a piece of code when the broker is started, you can perhaps base it off either an embedded Camel route or broker interceptor. The idea being that when the broker is started, so will these components and thus allows them to issue whatever sort of notification you require.
I am required to set up a keepalive endpoint to my web application (tomcat war).
The endpoint will be sampled periodically by my WAF to make sure that the app is healthy.
A healthy app means that the application is up and the communication to the RabbitMQ server (version 3.5.3 /spring-rabbit 1.4.5) is up and functional.
I will open some REST API to my WAF that will verify the connection status.
Reading the documentation I am quite lost on how to implement this functionally.
I noticed some functionality that may help, but I am not sure:
Enable automatic recovery and use RecoveryListener and make sure that the last recovery did not fail.
Configure HeartBeat and figure out a way to be notified on “disrupted connections”
Create some Heath Queue and use a plugin like Shovel to echo back the message, if I do not get any response I assume the queue is down
You don't need anything special like shovel to implement a health check. Just create a health queue and send/receive to/from it.
If you are using Spring AMQP
rabbitTemplate.send("", "healthQueue", "foo");
String foo = rabbitTemplate.receive("healthQueue");
In addition, you can register a ConnectionListener with Spring AMQP's connection factory and you will be notified when the connection is created/closed.
Spring AMQP has had connection recovery from the beginning so the (relatively new) built-in auto recovery in the rabbitmq client is not used.
If you are not using Spring AMQP use basicPublish and basicGet on a channel to send/receive to/from a health queue.
I am considering an architecture where I have clients that are intermittently connected to a network. I would like to store messages created on these clients in a JMS queue when the network is not available and have these forwarded to a central message broker when the clients are on the network. (The user has control over the network, e.g. dialing in, so it's not an intermittent connection like with a mobile phone.)
Are there any JMS implementations that provide this feature?
You can embed an activeMQ broker into your application
http://activemq.apache.org/how-do-i-embed-a-broker-inside-a-connection.html
Then, I suppose (did not test) that you could use ActiveMQ features which allow you to dispatch messages accross a net of brokers, using the discovery of brokers feature,
http://activemq.apache.org/clustering.html
or simply by adding a queue consumer server side, then dispatching through other brokers through this consumer.
Hope it helps.
The Glassfish Open Message Queue can be embedded (or run stand-alone) in version 4.4 (Support the ability for a broker to run "in process" with any client.). It is very light-weight, and will support other client languages over the STOMP protocol in version 4.4 - besides Java and C. - https://mq.dev.java.net/4.4.html