简体   繁体   中英

Jms How to know subscriber is not alive anymore

I have a distributed system application that uses JBoss as an application server. I have a client application that serves as a simulation engine. When client is up, it sends an registration message(JMS message) to Server, then some field is set in the database. When Server is up, it sends a message ( a topic) to all clients to check that they are alive. If clients are alive, they can read message and send a response to server (queue) that it is alive.

If user close client normally, client send a message to server that I will unregister. Then server unregisters it. This is done in database side.

If user close client abnormally(kill) , then client can not send a message to server for unregistration. Then server does not know this client is not alive anymore. This causes inconsistency in my application. So I need a way to understand that client subscribed a topic is not subscribed anymore.

Server sends a message to topic to check that clients are alive.

@Schedule(hour = "*", minute = "*", second = "30", persistent = false)
public void sendNodeStatusRequest() {
    Message msg = MessageFactory.createStatusRequestMessage();
    publishNodeMessage(msg);

}

After a time, Server show following logs. Could I catch this warning from Java?

07:17:00,698 WARN  [org.hornetq.core.protocol.core.impl.RemotingConnectionImpl] Connection failure 
 has been detected: Did not receive ping from /127.0.0.1:61888. It is likely 
 the client has exited or crashed without closing its connection, or the 
 network between the server and client has failed. The connection will now be  closed. [code=3]
 07:17:00,698 WARN  [org.hornetq.core.server.impl.ServerSessionImpl] Client 
connection failed, clearing up resources for session 4e4e9dc6-153e-11e7-
 80fa-742b62812c29

To me the whole point of messaging system is decoupled communication. The sender (server in your case) send its stuff to the topic without actually knowing who will get the message. The clients come and go, and they should be able to read the message whenever it (still) resides in the topic.

Now from your question I understand that the server keeps track of all the connected clients by means of receiving the message back to the dedicated queue.

So I'm asking myself - maybe its something wrong with the design here.

Let me propose slightly different way of implementation. The server should not be aware of any client, at most (because your system seems to work this way) it should know that client A, B and C are alive now only because these clients passed to the server this knowledge .

Why just don't make clients sending the "keep-alive" message every, say 1 minute (or less, depending on your needs) to the server queue without prior message from the server. The message can include some client identifier and probably time if its not added by the infrastructure or something)

So the server will just get this message and it will keep track in memory the list of available clients along with the last time they've sent something. So if some client disconnects "gracefully" - it can send a special message to the server like "I'm client A and consider me disconnected". Otherwise (abnormal termination/network outage/whatever) - it just won't send anything, the server will have a special process that will check whether there are stale clients on the list and if it finds them - it knows that something went wrong.

If you still want to stick with JMS way of doing, then you can try to send the message synchronously, meaning the producer will wait until it hears from the consumer. More information here : http://docs.oracle.com/javaee/6/tutorial/doc/bncfa.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM