I have developed an RMI application where the RMI server has to be started several times and also has to stop several times.
How can I stop the RMI server without closing the application?
How do I send notifications to all clients that the server is going to stop?
I'm not sure what you mean with the "RMI server", the RMI registry you cannot stop programmatically. But you can stop your service (bound to the RMI registry). You should invoke a custom method to cleanly shutdown your service and then unbindit from the registry.
Before this shutdown and unbinding you should inform all connected clients that the service will be shut down. This notification can be done by callback. Searching for RMI callback will give you a lot of examples and tutorials.
You don't really need to send a notification. Clients of an unexported remote object will get a NoSuchObjectEzception next time they do a remote method invocation on it. They just need to recognize the situation.
Related
I am following the Java RMI tutorial from here to build an example compute engine where the clients can submit tasks to a known server, and which the server will perform the task and return the result.
Having compiled and created new tasks sucessfully I want to learn further by reversing the logic, i.e. the server sends the task to the clients.
How would I conceptually do this? If I have understood correctly, the RMI server exposes the executeTask() method, which a client calls upon connecting to the server. I am toiling with turning each client into a 'server', each running an RMI registry and another application will connect to each of the rmi registries and call the executeTask method, and thus download the class.
Is there an obvious apporach in the logic I am missing? Having multiple RMI registries seem's incorrect.
What I want to end up with is a server with exposed RMI registry. All clients connect to server, server calls executeTask() method on each client to process the task on the clients. Ofcourse the task class needs to be located at the server and downloaded dynamically to the clients (currently the task is located at the client and sent to the server).
Have the server expose a fetchNextTask() method, and have the clients call it when they're ready to perform another task.
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?
Suppose I have an RMI Client-Server application. Clients connect to the Server and at some point the Server starts a task. During the task Clients are doing some work, but at some other moment the Server must interrupt this work without letting the Clients finish it. Clients are implemented as Threads and the simplest solution looks like calling thread.interrupt(), but this does not work in RMI. Is there any other method or some workaround to resolve this problem? Thanks in advance.
You can implement a two-way remoting scheme in which, when a client performs the lookup for the server remote object and creates the local instance, it calls a method by which it passes a remote object of its own to the server. Then, when the server has finished its task, it can notify the client by calling a method in the remote object received from the client.
I have written a program in Java which creates a socket connection for a simple online game. The server is multiclient and has a list of users logged. When I close the client it sends to the server a message to log out the user. I also want that when the client is terminated with the "terminate" button of Eclipse (or with Windows task manager) the client sends the same message. I tried with a ShootdownHook but it does not work. Any idea?
Thanks.
In order to have a robust system, you will at some point need to implement a heartbeat mechanism that allows the server to close connections. For example, if a client hasn't set a heartbeat in the last 30 seconds, then close the connection. Consider the case where the network between client and server goes down... or the machine the client is running on dies an ugly death. In those cases, you cannot rely on the client's logout message getting to the server.
Having said that, I suspect that shutdown hook is too late to do actual network IO. I have successfully used shutdown hooks to close connections. So you will need to have a more formal shutdown where the message is sent before other shutdown activity -- especially closing connections -- is initiated.
Nothing you can on the client side can act in the event of the red square in Eclipse. It terminates the jvm 'with extreme prejudice' -- no code runs. No hooks, no nothing.
You have, as #Dilum explained, to cope on the server side.
I'm building a Client / Server app that has some very specific needs. There are 2 kinds of servers: the first kind provide most of the remote procedures and clients connect to these directly, while the second kind is a single server that should keep track of what users are active (clients) and how many servers of the first kind are active when a method is called.
The main thing is that the monitor should ONLY connect to the servers and not the clients directly. My first idea was to implement a simple login/logout rmi method when a client connects/ disconnects and keep track of those in a list but the main problem is when a client or server end abnormally.
For example, if a client goes offline abruptly the server should somehow be notified and update the list accordingly, while if a server goes out all of the clients connected to it should be marked as not active in the control server.
Any ideas of how to implement this functionality would be appreciated.
I would suggest implementing a "session" approach to the problem, where the servers and the clients are sending a "heartbeat" method call to the monitoring server every several minutes(may seconds or hours depending on your needs). If the monitoring server doesn't receive a "heartbeat" from the servers or clients in a certain amount of time, then you consider them gone (terminated abnormally) and notify accordingly.
Zookeeper may be something to look at. Have each clientserver register an ephemeral node for itself, and for each client that is connected to it. When the clientserver goes down, the ephemeral nodes will die. The monitor server just needs to watch zookeeper to see who is up and connected.
For detecting clients going down, you will need some kind of hearbeating so that the clientserver can detect when a client dies. If the client can talk to zookeeper directly, then simply have the client register an ephemeral node in zookeeper as well, and the clientserver can watch the clients ephemeral node, and know when the client is down.