Gen_bunny (Erlang / Elixir) subscribe to queue (Rabbitmq) using bunnyc - erlang

Does anyone know how can I subscribe to Rabbitmq queue using gen_bunny?
I am able to connect and push the message and by using get method I can also receive message. However, I cant find out how to subscribe to a queue and get the message in my gen_server.

Related

Suave runs out of sockets when receiving messages from AWS' SNS service

This is linked to question: Suave stops responding with "Socket failed to accept a client" error
When I first started to use Suave, I was taking commands from a 3rd party service pushing messages and I would have an out of socket situation.
There is now more understanding of the problem:
I am receiving messages that are posted to the SNS service on AWS (it's just a queue). SNS will forward me each message it receives through a HTTP connection, as a POST message.
If I reply with Ok, I will run out of sockets. So this means that Suave is trying to keep the connection open and AWS is somehow initiating a new connection every time.
If I reply with CLOSE, the AWS' delivery starts to become odd and messages get delivered in batches followed by periods of nothing.
Since AWS will not change their system for me, I'm wondering if I can reply Ok but then somehow close the connection in Suave to not run out of sockets. Is it possible?
Or, is there a better way to handle this?

MQTT - How to know is message received by device

We have mqtt producer and consumer.
MQTT producer is at client level.
When we push message to producer, if the device is switched on, then it will receive the message.
If the device is switched off, then it wont receive the message until it turned on.
We need to know, when message sent to MQTT in server, if server is switched off, then we need to know the status as, it is queued or not received by server.
Based on it, we will send message for the user as, Please turn on device to do specific action.
Is there any better approach to know the status in MQTT to find is message is delivered or failed or queued to know server is active or not.
There is no end to end delivery notification in the MQTT protocol. Part of the pub/sub paradigm is that the publisher should be decoupled from the subscriber, there can be anywhere from 0 to many subscribers to a given topic.
There are 2 approaches to how to potentially work round this.
Have the subscriber respond on a separate topic to acknowledge that it has received the message. You will need to include a unique identifier in the message payload so it can be used in the response message.
You can use the Last Will and Testament feature of MQTT to have the subscriber maintain it's current status. When it starts it publishes a retained message to a known topic, e.g. publishes true to consumer/12345/status and sets a LWT to publish false if the device goes offline unexpectedly. It should also publish false if it cleanly shuts down. That way the publisher can check the status of the subscriber before deciding to publish the message.
I don't know which broker you are using. But in EMQ X MQTT broker, when QoS > 1, the message terminated delivered or ack broker will notify the server
The plugin: emqx-web-hook

Consumer Processing Timeout?

Here is our scenario:
We are publishing messages to a topic, and have a queue subscribed to that topic. We have several node.js consumers connected to that queue to process incoming messages, via the solclient package.
What we want to do is process the incoming messages, and after successfully processing the message, acknowledge the message so that it is removed from the queue. The challenge we're having is how to deal with error conditions. We are trying to figure out how to flag to the broker that the message failed to be processed? The expectation would be that the broker would then attempt to send to a consumer again, and once max redeliveries is hit, it moves to the DMQ.
I don't believe there's a way in Solace for a consumer to "NACK" a received message to signal an error in processing. I believe your option would be to unbind from the queue (i.e. disconnect() the Flow object, or MessageConsumer in the Node.js API) which will place allow any unacknowledged messages back on the queue and available for redelivery, and then rebind to the queue.
Alternatively, if you do your processing in the message received callback method, you could throw an exception in there, and that should (?) accomplish the same thing. But probably a lot less graceful.
https://docs.solace.com/Solace-PubSub-Messaging-APIs/Developer-Guide/Creating-Flows.htm
https://docs.solace.com/API-Developer-Online-Ref-Documentation/js/solace.MessageConsumer.html#disconnect

How to know the remote device is online using mqtt

How to know the remote device is online using mqtt (as a device simulator I am using MQTTfx). After publishing to a topic I am not getting any acknowledgement message and in the callbacks I am getting the same payload data that is published.
You can not find out is another MQTT client is online at a protocol level, in fact at a Pub/Sub pattern level a publishing client should not care is 0 or an infinite number of other clients are subscribed to the topic that message is published on.
The callbacks are only an indication that the message has been successfully delivered to the broker not to any of the subscribers. There is no end to end delivery notification (because there may be no subscribers to a given topic).
If you need to know the status of devices then you need to implement this yourself, the usual pattern is to use a status topic with a retained message and the LWT to clear this if the client crashes and setting it manually when it starts up or shuts down cleanly.

Broadcasting message to all connected users using websocket (Erlang, RabbitMQ, Websocket, Gen_bunny, Cowboy)

I am trying to integrate websocket chat using ERlang, Cowboy, Websocket and gen_bunny.
I am able to get them work independently.
Browser -> Cowboy websocket chat (Works)
Erlang and RabbitMQ AMQP (Works)
When integrating them together i am able to get the message from browser to Cowboy and pass it to RabbitMQ and again get it back from RabbitMQ.
I can even reply the message to the user who sent it. However, I want to broadcast the message to all connected Users.
As per my understanding Erlang will create a separate process for each user. So, how to broadcast it to all connected users after I get back the response from RabbitMQ??
Correct--Cowboy creates a per-connection process that runs your WebSocket handler code. One approach is to have the handler's websocket_init/3 function register itself with a "broadcast" process (and unregister in websocket_terminate/3). Upon receiving a message from RabbitMQ, the broadcast process repeats the message to all registered WebSocket connections, which can receive it using the websocket_info/3 handler callback.
The broadcast process can use monitors to discover when a WebSocket handler dies, and automatically remove it from the registration list.
The life of a handler, then, might look something like this:
websocket_init/3 is called after Cowboy performs the protocol upgrade requested in init/3 (to WebSocket). From here, the client handler registers itself with broadcast, the message broadcasting process.
As long as the connection remains open, the handler receives message broadcasts to its websocket_info/3, passing messages along to the client by returning {reply, {text, Message}, State}.
Upon termination, the handler unregisters itself with broadcast. If for some reason this doesn't work as intended, broadcast keeps monitors on all subscribers so as to get notified of their deaths.
Take a look on gproc project: https://github.com/uwiger/gproc
It has a Pub/Sub pattern that you may use to build the chat you mentioned.
From gproc's wiki:
subscribe(EventType) ->
%% Gproc notation: {p, l, Name} means {(p)roperty, (l)ocal, Name}
gproc:reg({p, l, {?MODULE, EventType}}).
notify(EventType, Msg) ->
Key = {?MODULE, EventType},
gproc:send({p, l, Key}, {self(), Key, Msg}).
Every cowboy process get its own Rabbit queue. Broadcast would work with wildcard bindings. No explicit loop involved. You could make the subscription optional by not binding accordingly. See: How to setup queue such a way all subscribers get messages - Rabbit MQ

Resources