I'm using Paho to communicate with an MQTT broker and all the example I found (like this) do these 3 steps when performing an action (publish or subscribe):
connect to the broker
do action
disconnect
My question is: are there any drawbacks holding a connection for the whole life of the application instead of opening/closing it for each action? Isn't it a faster solution removing the time for opening the connection?
No, holding a connection open for the lifetime of the application is a fully expected usecase, it's the only real way you'd be able to subscribe to a topic and receive messages when they are published.
The protocol has built in ping messages to ensure the broker knows the client is still connected.
The examples tend to be relatively trivial but want to show the full life cycle of the client which is why they connect, do something, disconnect
Related
I am looking into Amazon IoT as a transport mechanism for mobile devices periodically measuring data (usually every N minutes, with N being anywhere between 2 and 32 minutes). With MQTT, I can utilize Amazon's broker to publish finished measurement results to subscribers with QoS=1. Let's also assume that my sole subscriber is just another device listening on wildcard topic (eg. abc/#) and storing published messages into a local database.
But now it's also possible that:
the publishing mobile devices have spotty/bad/no connection to the cell network,
the subscriber dies (reboots, software failure, hardware failure, maintenance, etc.)
Assuming I use the official Java SDK . What would happen to data published during these times when at least either of them is offline? Will the subscriber get all the messages it has been missing out on upon reconnect?
Also: does this depend on the protocol in question? For testing purposes, we're using WebSockets, but later development/production, we'd prefer MQTT over SSL.
What would happen to data published during these times when at least
either of them is offline? Will the subscriber get all the messages it
has been missing out on upon reconnect?
Yes, If you use MQTT with QoS Level 1 or Higher because MQTT employs a Publisher/Subscriber architecture with Topic. Messages destined to Topics with QoS Level 1 and Higher will have the messages in memory and on disk (Atleast mosquitto) by the MQTT server until a Subscriber subscribes.
WebSocket is different. It doesn't have a Publisher/Subscriber architecture. It is a Duplex Communication model on a Single TCP connection. WebSocket initiates as a HTTP connection which will get updated to a WebSocket connection. In case of WebSocket it is the responsibility of the Application to make sure what happens when there are connection problems with Subscribers.
I have classic http client/server application where the server serves the clients data at their will but also performs some kind of call-backs to the list of clients' addresses it has. My two questions are :
1- How would the server know if a client is down (the client did not disconnect but the connection got suddenly interrupted) ?
2- Is there a way to know from the server-side if the process at client-side listening on the call-back port is still up (i.e. client call-back socket is still open) ?
1- How would the server know if a client is down (the client did not disconnect but the connection got suddenly interrupted) ?
Option #1: direct communication
Client tells server "I'm alive" at a periodic interval. You could make your client to ping your server at a configurable interval, and if the server does not receive the signal for a certain time, it'll mark the client as down. Client could even tell server more info(e.g. It's status) in each heartbeat if necessary, this is also the way used in many distributed systems(e.g. Hadoop/Hbase).
Option #2: distributed coordination service
You could treat all clients connected to a server as a group, and use a 3rd party distributed coordination service like Zookeeper to facilitate the membership management. Client registers itself to Zookeeper as a new member of the group right after booting up, and leaves the group if it's down. Zookeeper notifies the server whenever the membership changes.
2- Is there a way to know from the server-side if the process at client-side listening on the call-back port is still up (i.e. client call-back socket is still open) ?
I think this can only be done by the way Option #1 listed above. It could be either the way clients tell server "My callback port is OK" at a fixed interval, or the server asks clients "Are your callback port OK?" and wait its response at a fixed interval
You would have to establish some sort of protocol; and simply spoken: the server keeps track of "messages" that it tried to sent to clients.
If that "send" is acknowledged, fine; if not: then the server might do a limited number of retries; and then regard that client as "gone"; and then drop any other messages for that client.
1- How would the server know if a client is down (the client did not disconnect but the connection got suddenly interrupted) ?
A write to the client will fail.
2- Is there a way to know from the server-side if the process at client-side listening on the call-back port is still up (i.e. client call-back socket is still open
A write to the client will fail.
The write won't necessarily fail immediately, due to TCP buffering, but the write will eventually provoke retries and retry timeouts that will cause a subsequent read or write to fail.
In Java the failure will manifest itself as an IOException: connection reset.
How much is the overhead of creating following objects everytime sending the message to queue?
Objects: javax.jms.Connection, javax.jms.Session, javax.jms.MessageProducer
In my code, Whenever I want to send a message, I am creating above 3 objects.
I know its good to create object only once and use it but the connection/session goes into IllegalState after Server Failover. My connectionFactory is able to reconnect but it is not able to refresh connection/session object.
Can someone please explain me the overhead?
https://developer.jboss.org/wiki/ShouldICacheJMSConnectionsAndJMSSessions
High Performance JMS Messaging
:)
It is always a costly affair to create a connection and session to a messaging provider every time. Every time a connection is requested, the underlying messaging library has to create a socket connection to messaging provider, flow some handshake data and establish a channel using which messages can be sent. After message is sent, connection close also requires some messaging provider specific data to be sent across to gracefully close connections.
You can quantify the overhead by running some tests with and without creating connections/session every time. But the above explanation gives a hint on what would be involved in creating/closing a connection.
I am looking to build an instant messenger in Java.
Clients will connect to the server to log in.
They will start a conversation with one or more other clients.
They will then post messages to the server that will relay the messages to all the clients.
The client needs to be continually updated when users post messages or log in.
so the way I see it, the client needs to run a server itself in a separate thread so that the main server can send stuff to it. Otherwise the client will have to the poll the main server every xyz seconds to get the latest updates. And that would need a separate thread anayway, as that would be purely for getting updates whereas the 'main' thread would be used for when the client initiates actions such as posting messages/inviting others to conversations etc...
So anyone recommendations on how to write this instant messenger? Does it sound like a good idea to make the connection a 'two-way' connection where both the client and server act as servers? Or is polling a better option? Anyone know how the IRC protocol does this?
There's no real advantage of having 2 connections unless they can be handled independently (for example receiving / sending a file usually done in a separate connection). A connection itself is already a two-way communication channel so it can be used to both send and receive messages, events etc. You don't need to poll server since client is able to maintain persistent connection and just wait for data to appear (optionally sending periodic PING-like message to ensure connection is alive).
IRC uses a single connection to server to exchange text commands. For example one of the main commands:
PRIVMSG <msgtarget> <message>
This command can be originated either by client or by server. Client sends PRIVMSG to notify that it wants to deliver message to one or more destination (in IRC this either user(s) or channel(s)). Server's task here is to properly broadcast this message to appropriate clients.
If you're using raw InputOutput streams then yes this is a good way of doing it. You create one thread on the clientside that acts in a similar fashion as the server thread - waits for any incoming updates and when it does it updates the client. I wouldn't call it a server though. So you'd ideally have 2 TCP/UDP connections one for requests made by the client and one to notify the client of server changes.
This solution in an enterprise environment would probably be done through some kind of messaging framework such as Spring Integration but dig deep enough and it will essentially be a similar way to how you mentioned.
Do you need a fully custom protocol or would it be sufficient to use the XMPP? There are several open source libraries implementing XMPP.
http://xmpp.org/xmpp-software/libraries/
e.g. http://www.igniterealtime.org/projects/smack/
For me, to develop instant messaging service, I will use websocket protocol instead of normal java socket because the normal socket can not work well with HTTP protocol and moreover some network providers and firewalls banned custom ports. If you develop it in normal socket, your service could not be accessed by web clients.
Did you plan to develop the instant messaging service yourself? How about using other protocols such as Jabber?
I just programmed a Java Server-Client Chat (with multiple clients) where they log in, chat and log out. The socket is always started and I listen in a loop.
Now I have to program this kind of chat where the connection isn't always open, so the the connection just stars "on request" (when someone sends a message).
How do I do this? Could you give me some keywords which I should google?
If you want to create a Server and Client that does not have a Open Connection (Correct me If I am wrong) you will have to Open and close the connection manually. As these "connections" represent Streams across the network.
Another Option you can consider is maybe using UDP, but this does not close and open a connection on request it only removes the overhead of TCP and it's reliability features.
From the Datagram Lesson on Oracle.com:
Some applications that you write to
communicate over the network will not
require the reliable, point-to-point
channel provided by TCP. Rather, your
applications might benefit from a mode
of communication that delivers
independent packages of information
whose arrival and order of arrival are
not guaranteed.