How to handle read() first with spring integration TCP outbound gateway - spring

I'm implementing a tcp client which will send request to a server and expect an response. But when the client 1st connect to the server, the server will send a hello msg, with tcp outbound gateway, it expects to send then receive. How can I do receive (only when first connect) then do my usually send and receive logic? And if I need to keep the connection alive, is there a way to send keep alive msg to the same connection by some scheduling task?

Instead of a gateway use Collaborating Channel Adapters for completely async operations.
Collaborating adapters can also be used (server-side or client-side) for totally asynchronous communication (rather than with request/reply semantics).
You can use operating system keep alives (SO_KEEPALIVE). Or you can roll your own application-level keep alives with a polled inbound channel adapter...
<int:inbound-channel-adapter channel="toTcp" expression="'foo'">
<int:poller fixed-delay="60000" />
</int:inbound-channel-adapter>

Related

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

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.

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).

ZeroMQ XPUB socket dropping packets until subscriptions arrive

I understand an XPUB socket can drop messages that are sent on it until
it sees some forwarded subscriptions that match. Makes sense.
However, my XPUB process has restarted, and subscribers on other machines
are up and running for a while, but for a period of minutes, all messages I send
on the XPUB socket are silently dropped, until the XPUB socket receives
the forwarded client subscriptions.
I'm using a XPUB/XSUB proxy as an intermediate here. Nothing fancy here.
Is there any way to trick zmq to forward subscriptions to the new XPUB socket
which has connected to the proxy in a more timely manner?
I've thought about queuing the messages on the XPUB side until the subscription
message arrives, or perhaps implementing something in the proxy server to
cache the last subscription request, and use zmq_monitor_socket() to look for
new connections and then forward the cached subscriptions, but these both
seem kind of hacky.
is it only the xpub thats restarted or do both xpub/xsub sockets restart, I am using nodejs zmq and in my experience my messages are still forwarded when my xpub/xsub proxy restarts..

zeromq DEALER client to multiple servers (ROUTER)

I am using ZEROMQ for distributed messaging application. Need to connect client (DEALER socket) to multiple servers (ROUTER socket on server side). What are my options on CLIENT side ?
Create DEALER socket on client side for each server endpoint (ROUTER socket).
Create only ONE DEALER socket on client side and add multiple endpoints.
I tried option 2 - connecting to multiple endpoints but message always goes to the first connected endpoint. followed following steps:
create DEALER socket
connect to first endpoint
then at run time, add another endpoint to the socket by using socket.connect(endpoint).
Do I need to reconnect?
In DEALER socket, there is no option to send message on a particular endpoint in case it is connected to multiple endpoints.
Any idea?
ZeroMQ encodes certain behaviors into socket types. These mainly deal with:
handling multiple peers
handling undeliverable messages
handling excessive throughput (HWM)
A DEALER socket is one that can connect to multiple peers, and uses LRU (least recently used, aka round-robin) to decide which peer gets each message. If you do not want this behavior, then you do not want a DEALER socket with multiple peers.
If you want to decide which peer gets a message, there are two options for this:
create a DEALER per peer, and send on the appropriate socket
create a single ROUTER connected to all peers, and use IDENTITY prefixes to route messages. You may need to pass IDENTITIES via a side channel, in order to use ROUTER-ROUTER connections.
at run time, add another endpoint to the socket by using socket.connect(endpoint). Do I need to reconnect?
No, you do not need to reconnect. You can add (and remove) peers at any time during the program.

Does ZeroMQ ROUTER socket maintain order when using TCP as transport?

I went through some examples using ZeroMQ and found this asynchronous messaging example using a ROUTER socket at the frontend of the server. The documentation states that on incoming requests this socket type will "fair-queue" incoming requests. However, if TCP is used, does that socket maintain order of incoming requests from the same client? For example if client A sends a Message M1 and then M2, the socket will forward M2 after M1 right?
Yes, you can assume that the ordering a client ØMQ sends messages will be received in the same order on the other side. Conceptually, you think of ØMQ Sockets as a message queue.
http://www.aosabook.org/en/zeromq.html#fig.zeromq.arch

Resources