Handle Sink.tryEmitNext() for one session - spring-boot

How to handle the sinks.emitEvent based on session. I have implemented the sink but the message I push is received by all the clients, but I want seperate context for seperate clients for server send events

Related

Websocket from UI connecting to one of the instances for Spring boot application for streaming the data coming on a queue

I have an UI application (displays streaming) which makes a WebSocket connection to the Spring Boot microservice (multiple JVM'S) and this service forwards the request to one of the upstream servers and listens to the responses on a JMS queue coming from upstream server, which then response messages had to be returned to the socket.
Issue we are facing is since the socket is point to point, and the Spring Boot application is running on multiple instances which all are listening to the same JMS queue we are unable to serve the data back to the WebSocket when a message is received on a instance which the request to upstream wasn't made.
Here's the basic flow:
WebSocket -> instance1, instance2, instance3 -> Data provider
Instance1 made the request to data provider.
Data provider sends the data back to the queue
Instance 3 receives the message, but it doesn't have the socket connection to send the data back.
We had an interim solution using correlation id in JMS headers and selectors on the queue however now the data publisher is not able to provide the correlation id to depend on.
Does anybody have a better suggestion to address this?
Since you're using a request/reply pattern with JMS you must either use a correlation ID or a unique temporary queue for the response.
You indicated that, "the data publisher is not able to provide the correlation id to depend on." However, your application actually provides the correlation ID. The "data provider" in this case just needs to take it from the message it receives and put it into the response message. The process only requires 2 method calls by the "data provider" - javax.jms.Message.getJMSCorrelationID and javax.jms.Message.setJMSCorrelationID.
If the "data provider" can't do this then it's doubtful they will be able to accomplish the other option of using a unique temporary queue for the response. However, it's worth explaining in any case. When one of your "instance" servers sends the request message it first needs to use javax.jms.Session.createTemporaryQueue to create a temporary queue and then take the return parameter of that method and set it on the request message using javax.jms.Message.setJMSReplyTo. When the "data provider" receives the message they will get this value using javax.jms.Message.getJMSReplyTo and then send the response to this queue where the "instance" will then retrieve it.
These are the two generally accepted ways to implement a request/response pattern with JMS. I don't know of any other ways to implement such a pattern.

Websockets: One handler to rule them all? Best case w/ backups?

I'm working on making an iOS app that does a few things, some of which would benefit from real-time data streams (like chat)
For right now I have a few handlers on my server, one of them gets all the threads a user has access to, another can get messages (offset, all, time-ranged, etc.) for a thread. When a user sends a message to a thread, I get all the listeners for the thread and send them a push notification. This works, but I was reading through the APNS docs and it says "dont do more than 3/hr" and I'm definitely doing more than 3/hr.
So I'm thinking I move to websockets. I know how to synchronize pub/subs across machines via redis so I'm not worried about that, I'm more stuck on the following:
If I start to bring websockets into the project, should I just pump all the information App <-> Server through the websocket? Create a thread -> Don't POST, just send a message along the socket. Get a message -> Don't poll or send notification, just send a message along the socket. Literally anything -> Don't make a request, just send a message along the socket.
Right now I'm leaning towards loading initial state and bulk data via normal HTTP URLs (eg: Create a thread, load the last 20 messages for thread XYZ), but for data that needs to be pushed and received in real time (eg: Chat Message send/recv) do that via a websocket.

how to send message to a specific user by username at any application point

I am implementing spring boot stomp message broker socket to interact with webclient. i need to send sms to a specific user by username at some application point,means the message will be trigger from server to client. client will subscribe to a topic/queue. i heard #SendtoUser send sms to the perticular user, but here in my case user is just subscribing a topic, then from backend i need to send sms time to time to specific user. user will not send any sms to server.
its just push based sms.
messagingTemplate.convertAndSendToUser(sessionId,"/queue/something", payload,
headerAccessor.getMessageHeaders());
but here from where will i get the session id for the targeted user. here user is just subscribing the topic once.
You can find answer to a similar question (with project exemple) here :
Spring websocket send to specific people
The fact that user is subscribing once is not a problem. One the connection is established, the server can send has much message as needed.

Web Chat application - how to persist data properly?

We are currently implementing a simple chat app that allows users to create conversations and exchange messages.
Our basic setup involves AngularJS on the front-end and SignalR hub on the back end. It works like this:
Client app opens a Websockets connection to our real-time service (based on SignalR) and subscribes to chat updates
User starts sending messages. For each new message, client app calls HTTP API to send it
The API stores the message in the database and notifies our real-time service that there is a new message
Real-time service pushes the message via Websockets to subscribed Clients
However, we noticed that opening up so many HTTP connections for each new message may not be a good idea, so we were wondering if Websockets should be used to both send and receive messages?
The new setup would look like this:
Client app opens a Websockets connection with real-time service
User starts sending messages. Client app pushes the messages to real-time service using Websockets
Real-time service picks up the message, notifies our persistence service it needs to be stored, then delivers the message to other subscribed Clients
Persistence service stores the message
Which of these options is more typical when setting up an efficient and performant chat system? Thanks!
You don't need a different http or Web API to persist message. Persist it in the hub method that is broadcasting the message. You can use async methods in the hub, create async tasks to save the message.
Using a different persistence API then calling signalr to broadcase isn't efficient, and why dublicate all the efforts?

RabbitMQ Consumer Disconnect Event

Is there any way we can know when a consumer disconnects from a queue or when a queue is deleted?
The requirement is as follows:
I'm building a system in which multiple clients can subscribe to certain events from the system. All clients create their own queue and registers themselves with the system using some sort of authentication. The system, as the events are generated, filters the events and forwards them to clients who are eligible for them.
I have implemented a POC for most part of it and it works well. An issue that I'm not able to fix is that, if a client just disconnects from the queue (due to program termination or so), the registration still exists and the system keeps trying to push messages to that client.
So we would like to be notified when a client disconnects or a queue gets deleted so that we can remove that client's registration data and no longer push messages to him.
Let your publisher utilize Confirms (aka Publisher Acknowledgements) and make client queue be exclusive and transient, so only one client at a time will be consuming from one queue and after it disconnection it will be deleted.
If you publish message that get routed to only one queue and that queue gone (assume you utilize publisher confirms and publish message with mandatory flag set) publisher will be notified that message cannot be routed with that message returned back to it, so you can stop publishing messages.
For details see How Confirms Work section in RabbitMQ blog post "Introducing Publisher Confirms" and Confirms (aka Publisher Acknowledgements) official docs.

Resources