Next: 10 For further information Up: GNUstep Distributed Objects Previous: 8 Error checking -

9 Error checking - connection died

The other typical error which can occur is that a connection dies. As an example, suppose that we had a modified client, in which we get a remote reader object, and then loop waiting for the user to input a filename. When the user inputs a filename, we ask to the remote object to get that file, and we print it out, then we go back into the loop waiting for the user to input another filename.

In that situation, it might happen that the remote server is up and running, but at a certain point, while we are in our loop waiting for the user to input a filename, the remote server becomes unavailable (for example, because of a hardware crash, or because the network connection goes down, or because the server crashed with a segmentation fault during some operation). If the gnustep base library detects this problem, it invalidates the proxy to the remote object (which in plain words means that the reader object is no longer useful, and you should no longer use it), and posts the NSConnectionDidDieNotification notification. If we are observing that notification, we can be informed immediately that this problem has occurred, and we might manage it - we might want to exit the application immediately, or try to connect to another server, or inform the user that because the remote server is down, we will only fetch files locally till we can connect to the remote server again, or something else. In any case, the notification gives us an opportunity to release our reader object - which is no longer useful because the connection has died - and, if we want and if we can, to take some corrective measures. Here is the simple code needed to observe the notification:

 [[NSNotificationCenter defaultCenter]
    addObserver: myObserver
       selector: @selector(methodToExecuteWhenTheConnectionDies:)
          name: NSConnectionDidDieNotification
        object: [(NSDistantObject *)reader connectionForProxy]];
Calling this code after the reader object is created will cause the methodToExecuteWhenTheConnectionDies: of the myObserver object to be called when the connection to the server goes down.

Here is an example Client.m code which you can use as a starting point for playing with dying connections -

#include <Foundation/Foundation.h>


@protocol FileReader
- (NSString *)getFile: (NSString *)fileName;
@end

@interface Observer : NSObject
- (void)connectionDied: (NSNotification *)not;
@end

@implementation Observer
- (void)connectionDied: (NSNotification *)not
{
  NSLog (@"Connection to server died! - exiting");
  exit (1);
}
@end

int 
main (void)
{
  NSAutoreleasePool *pool;
  NSArray *args;
  int count;
  id <FileReader> reader;
  NSString *filename;
  NSString *file;

  pool = [NSAutoreleasePool new];
  
  /* Get program arguments */
  args = [[NSProcessInfo processInfo] arguments];
  
  /* Create our remote FileReader object */
  reader = (id <FileReader>)
    [NSConnection
      rootProxyForConnectionWithRegisteredName: @"FileReader" 
      host: @"*"];
  
  if (reader == nil)
    {
      NSLog (@"Error - could not connect to FileReader Server");
      exit (1);
    }
  else
    {
      NSLog (@"Connected");
    }
  
  
  /* Register Observer -connectionDied: to be informed if the connection
     to the server dies.  */
  [[NSNotificationCenter defaultCenter]
    addObserver: [Observer new]
    selector: @selector(connectionDied:)
    name: NSConnectionDidDieNotification
    object: [(NSDistantObject *)reader connectionForProxy]];

  /* Ok - now we enter the main run loop.  In this example, we just do
     nothing in the main run loop as I'm too lazy to code it to do
     something -- but you should imagine that this is a server doing
     a lot of stuff in the run loop, and using the 'reader' to fetch 
     files from the remote server when its activity in the run loop
     requires it.  */
  [[NSRunLoop currentRunLoop] run];

  return 0;
}
You can play by running the server in an xterm, then running the client in another xterm, then killing the server in the first xterm (for example by pressing Control-C): the client in the second xterm should be immediately notified that the connection to the server is dead!


Next: 10 For further information Up: GNUstep Distributed Objects Previous: 8 Error checking -
Nicola 2002-02-24