Archived
This forum has been archived. Please start a new discussion on GitHub.
how to send last message before server terminates in Ice::Application class?
ondrej
in Help Center
Hello,
I am using the help class Ice::Application and I would like to inform the clients about the fact that server is going to terminate. It means, when I call ctrl-c to terminate my server first a message should be send to the clients and then the communicator should be destroyed. The problem is that in the run() function I should use:
In the forum thread on : http://www.zeroc.com/vbulletin/showthread.php?t=1554
I read in the post #9 about a function
thanks a lot for your answer
ondrej
I am using the help class Ice::Application and I would like to inform the clients about the fact that server is going to terminate. It means, when I call ctrl-c to terminate my server first a message should be send to the clients and then the communicator should be destroyed. The problem is that in the run() function I should use:
communicator()-> waitForShutdown();Well this works fine but it deletes also the communicator- so I can't send anything afterwards.
In the forum thread on : http://www.zeroc.com/vbulletin/showthread.php?t=1554
I read in the post #9 about a function
virtual bool interrupt(int sig);. I think that is exactly what I need... the problem is just that I think this function doesn't really exists, at least I couldn't find it in the manual. Can I initialize such function on my own? I mean this function should be in the Ice::Application class. Or is it already there? ...or should I better use another method to solve this problem?
thanks a lot for your answer
ondrej
0
Comments
-
Thanks a lot for the fast reply,
but I can't still bring it to work. I am little confused with shutdownOnInterrupt(); because I don't know where in code I should use it- before or after communicator()-> waitForShutdown(); ? Or am I thinking in wrong way?
Here my code:int MudServer::run(int argc, char * argv[]){ Ice::ObjectAdapterPtr object_adapter = communicator()->createObjectAdapter("SeLinuxMudAdapter"); //create servant & add servant to adapter's map of servants-> it will be done in the constructor of the object WorldI IceUtil::Handle<WorldI> mud_world = new WorldI("SeLinuxMud", object_adapter); object_adapter->activate(); //critical part: destroyOnInterrupt(); //lineA //the next function should send a message to clients to inform them about termination of the server mud_world->last_message_to_clients(); //lineB communicator()-> waitForShutdown(); //lineC return 0; } int main(int argc, char * argv[]) { //class MudServer : virtual public Ice::Application MudServer mud_server; return mud_server.main(argc, argv); }
When I don't use communicator()->waitForShutdown(); logically my server will not wait for clients and terminates. When I use it and put after it the code as in "lineB" I get this message by terminating the server: Instance.cpp:189: Ice::CommunicatorDestroyedException:
communicator object destroyed . That's why I was thinking that when I use the function waitForShutdown() in Ice::Application also the communicator will be destroyed.
When I use destroyOnInterrupt(); like in the code I wrote now, it's the same as it would be not there.
Could be the problem that I want to use the function from the Ice Object "WorldI"? should I better give the function last_message_to_clients(); to an object that is not an Ice object?
When I should use shutdownOnInterrupt(); How I should use it? I know what this function should do- but I don't know how to use it right. Or am I doing somewhere a trivial mistake?
Thanks a lot for your answer and time.
ondrej0 -
ooh, I tried right now another possible combination and it was working:
shutdownOnInterrupt(); communicator()-> waitForShutdown(); mud_world->kill_players();
OK now I think I know how it works- the functions like shutdownOnInterrupt(); or destroyOnInterrupt() I should put always before communicator()-> waitForShutdown(); to set the behaviour of the application when it receives the signal. right?
thanks
ondrej0 -
Correct. You must use shutdownOnInterrupt() so that communicator->shutdown() is called upon interrupt. This way, waitForShutdown() will return, but your communicator will not be destroyed, and you can still invoke requests.
With destroyOnInterrupt(), an interrupt triggers communicator->destroy(), which destroys both the client and the server side of your application. That's why you get a CommunicatorDestroyedException if you attempt to invoke any requests after the interrupt.0 -
does it mean also that I should destroy the communicator afterwards explicitly when it is not destroyed by calling the function shutdownOnInterrupt()?
shutdownOnInterrupt();
communicator()-> waitForShutdown();
mud_world->kill_players(); //last_message_to_clients will be send
communicator()->destroy(); //<<<<????
I tried it with and without communicator()->destroy(); and there was no difference when I terminated the server- better said, I didn't get any exceptions. But it is better to call it? or it is not necessary?
thanks a lot
ondrej0 -
Marc is correct, in general you must always destroy the communicator instance. However, this is not necessary when you use Ice::Application because the communicator is destroyed after run() returns (but there is no harm in calling destroy on the communicator more than once).
Take care,
- Mark0
