Connect/disconnect from ActiveMQ topic on camel websocket connection/disconnection - websocket

I've got the following camel route which listens for messages on an ActiveMQ topic and immediately sends them to all connected web socket clients. This is working fine, but the connection to the topic is made as soon as the route builder is initialised.
from("activemq:topic:mytopic").routeId("routeid").to("websocket://test?sendToAll=true");
What I need is to only connect to the topic when one or more clients are connected to the web socket. Once there are no more connections I want to stop listening on the topic. Is this possible?

According to me there is no proper way to do this. The only way this can be achieved is override Jetty WebSocket code. Once you override Jetty Websocket code you get the flexibility to write your own custom code in open and close websocket.
Maintain a List for all websocket clients in open websocket. Check for close websocket and remove it from the list to know how many are connected or disconnected. Or keep a counter on open and close websocket.
Once all websocket clients get closed suspend the route so that your messages stay in the topic or queue.
If any client gets connected to websocket, resume the route so that the messages reach the particular client connected.

Related

Spring websockets + Amazon MQ limitations

We want to use spring websockets + STOMP + amazon MQ as a full featured message broker. We were trying to do benchmarking, to find out how many client websocket connections single tomcat node can handle. But it appears that we hit amazonMQ connection limit first. As per the aws documentation, amazonMQ has a limit of 1000 connections per node (as far as I understand we can ask support to increase the limit, but I doubt that it can be increased big time). So my questions is:
1) Am I correct in assuming that for every websocket connection from client to spring/tomcat server, a corresponding connection being opened from server to broker? Is this correct behavior or we're doning something wrong here/missing something?
2) What can be done here? I mean I don't think this is a good idea to create broker node per evry 1000 users..
According to https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/messaging/simp/stomp/StompBrokerRelayMessageHandler.html your are doing everything right, and it is documented behavior.
Quote from javadoc:
For each new CONNECT message, an independent TCP connection to the broker is opened and used exclusively for all messages from the client that originated the CONNECT message. Messages from the same client are identified through the session id message header. Reversely, when the STOMP broker sends messages back on the TCP connection, those messages are enriched with the session id of the client and sent back downstream through the MessageChannel provided to the constructor.
As for a fix, you can write your own message broker relay, with tcp connection pooling.

MQTT Broker as both Client and Broker

I have a regular cloud server set up, I have a mobile app talking to the server via HTTP requests. I also have a Wifi device that I need to send messages and I want to do that over MQTT. When some change happens on the mobile app, I want the cloud server to publish a topic via MQTT so that the wifi device can receive the message. Can a broker also be a client? Am I understanding it wrong?
I'm going to attempt an answer based on my understanding; sorry if I misunderstood your question.
The way I understand it, you will have three/four pieces of software:
HTTP Server / MQTT Broker (these two services could run in the
same application or in separate ones)
Mobile application (communicates over HTTP)
Wifi Device (communicates using MQTT protocol)
Scenario:
The Wifi device will open a connection to the MQTT Broker and subscribe to a well defined topic. You can use a subscription with a QoS of 1 if you cannot afford to lose the messages. Any messages published prior to adding the subscription will not be received by your client. It might also be useful to open an MQTT connection using a non-clean session if your wifi connection is unstable (again, if you don't want to lose any messages).
After a specific event, the mobile application which communicates with the HTTP server will send it information.
Upon reception of the information, the HTTP server will then send an MQTT message to the MQTT Broker on the predefined topic (a topic that will match the Wifi Device's subscription).
The MQTT broker will relay the message from the HTTP Server to the Wifi Device (and any other MQTT clients with a matching subscription).
I hope this clarifies, let me know if anything is unclear.
"Can a broker also be a client?" Not really, although I'm certain some specific brokers will publish messages to special subscriptions based on special events, it only acts as a broker. It receives messages from publishers and forwards messages to any client who has shown interest in that message using a subscription (the message could potentially be dropped by the broker if no subscriber (client) is interested in that message).

Erlang Pub/Sub using Redis and websockets

My goal is to create an application that I can use to manage pub/sub for various clients. The application should be able to receive new topics via an API and then accept subscribers via a websocket connection.
I have it working, but am aware the current solution has many flaws. It works currently as follows:
I have a chicago_boss app, that has a websocket endpoint for clients to connect to, once the client connects, I add the Pid for that Websocket connection to a list in Redis.
Client connects to "ws://localhost:8001/websocket/game_notifications"
The Pid for that Websocket connection is added to Redis using LPUSH game_notifications_pids "<0.201.0>".
3.The last 10 messages in Redis for game_notifications are sent to the websocket Pid
A new message is posted to "/game_notifications/create"
Message is added to redis using LPUSH game_notifications "new message"
All Pids in Redis with key game_notifications_pids are sent this new message
On closing of the websocket the Pid is deleted from the Redis list
Please let me know what problems people see with this setup? Thanks!

Are AMQP connections (RabbitMQ) between Cloundfoundry applications possible?

I have two applications deployed on Cloudfoundry: a service application that computes stuff (aka computeService) and a client application that renders html for us mortals to hit buttons on (aka clientService). I would like a controller in the clientService to send commands to the computeService (when mortals hit buttons). The broker and the computeService run on the same machine.
I know I cannot make remote AMQP connections into a service on cloudfoundry.com, but I assume I can make connections between applications. However, every sensible address combination for broker and clientService gives me the same error:
javax.jms.JMSException: Could not connect to broker URL: tcp://127.0.0.1:61616. Reason: java.net.ConnectException: Connection refused
Whatever address I try, I cannot post to the queue. The code works flawlessly on my local machine.
My question: can I use RabbitMQ to pass messages between the two applications on Cloudfoundry? And if so, which addresses should I use?
Thanx!
One way to try this out is to create two replicas of the rabbit message example at Spring Samples
...a message sender and a message receiver. When deployed, they should share the same rabbit service.
I pushed the rabbit message which worked for me to: rabbitmessage-sndrcv

RabbitMQ with Websocket and Gevent

I'm looking forward to develop a realtime API for my web application using Websocket. For this I'm using RabbitMQ as the broker and My backend is based on python (gevent + websocket),and Pika/Puka as rabbitmq client.
The problem I'm facing here is that, how we can use websocket to connect with rabbitMQ. After the initial websocket connection establishment, the socket object wait for new messages from client, and in the case of rabbitMQ, we need to setup a consumer for it, so it will process the message when it receive one. We can take this in this way,
Clients are established connection with server via full-duplex websocket.
All clients should act as RabbitMQ's consumer after initial websocket handshake, so they all get updates when a client gets some message.
When new message arrives at websocket, that client will send it to RabbitMQ, so at this time this client act as publisher.
The problem is Websocket wait for a new message, and the RabbitMQ consumer wait for new message on its channel, I'm failed to link these two cases.
I'm not sure whether this is a wrong method ...
I'm unable to find a method to implement this scenario.If I'm going wrong way or is there any alternate method ?, please help me to fix this.
Thank you,
Haridas N.
I implemented similar requirement with Tornado + websocket + RabbitMQ + Pika.
I think this were already known method. Here is my git repo for this web chat application.
https://github.com/haridas/RabbitChat
It seems very difficult to the similar thing with gevent/twisted because the rabbitMQ clients couldn't supporting the event loops of gevent/twisted.
The pika has tornado adapter, so that makes this easy to setup. Pika development team working on the twisted adapter also. I hope they will release it very soon.
Thanks,
Haridas N.
http://haridas.in.
A simple solution would be to use gevent.queue.Queue instances for inter-greenlet communication.

Resources