[Q] Remote Messaging : Keep sending msg to a destroyed remote object

  • Hello.

    I wrote a simple test program for remote messaging.
    Strangely the client program can send message to a destroyed remote
    object and the remote object responds correctly.

    On the server, there are two buttons : One for making an object to
    expose and register it. The other is to destroy the object and
    unregister it.

    The server side code is :

    // createRemoteObject button : create an object to expose and expose it.

    - (IBAction)createRemoteObject:(id)sender
    {
      m_serverObject = [[ServerObject alloc] init];
      [m_serverObject setView:scrollTextView];
        theConnection = [NSConnection defaultConnection];
      [theConnection setRootObject:m_serverObject];

      if( [theConnection registerName:@"server"] == NO )
      {
          [[[scrollTextView textStorage] mutableString] appendString:@"The
    server object is not registered.\n"];
      }
      else
      {
          NSMutableString *mutableString;
                mutableString = [[scrollTextView textStorage] mutableString];
          [mutableString appendString:@"The server object is
    registered.\n"];                }
    }

    // destroyRemoteObject : unregister the object, destroy it, and send
    notification to the client

    - (IBAction)destroyRemoteObject:(id)sender
    {
      if( m_serverObject )
      {
            [theConnection registerName:nil];

            [m_serverObject release];
            m_serverObject = NULL;

            [[NSDistributedNotificationCenter defaultCenter]
    postNotificationName:@"remoteObjectDestroyed" object:@"RemoteServer"
    userInfo:nil deliverImmediately:YES];

            [[[scrollTextView textStorage] mutableString] appendString:@"The
    server object is destroyed.\n"];
        }
    }

    The client have a few buttons : one for getting the remote object,
    others for sending messages to the remote object.

    // getRemoteObject
    - (IBAction)getRemoteObject:(id)sender
    {

      serverProxy = [[NSConnection
    rootProxyForConnectionWithRegisteredName:@"server" host:nil] retain];
        if( serverProxy == nil )
          exit(1);
        [serverProxy setProtocolForProxy:@protocol(ServerProtocol)];
      }

    // init add this object as an observer to "remoteObjectDestroyed"
    distributed notification
    - (id)init
    {
        if ((self = [super init]) != nil)
        {
            [[NSDistributedNotificationCenter defaultCenter]
    addObserver:self selector:@selector(remoteObjectDestroyed)

    name:@"remoteObjectDestroyed" object:@"RemoteServer"
                suspensionBehavior:
    NSNotificationSuspensionBehaviorDeliverImmediately];
      }
      return self;
    }

    - (void)remoteObjectDestroyed
    {
      [serverProxy release];
      serverProxy = nil;

      [[[logView textStorage] mutableString] appendString:@"The remote
    object is destroyed.\n\n"];
    }

    - (IBAction)avgAge:(id)sender
    {
      if( serverProxy )
      {
          int num = [serverProxy avgAge];
          [[[logView textStorage] mutableString] appendFormat:@"Avg. Age =
    %d\n", num];
      }
      else
      {
          [[[logView textStorage] mutableString] appendString:@"No
    serverProxy\n"];
      }
    }

    For example, avgAge is a method of the remote object.

    So, on the server side, I pressed the "Create Remote Object" button, and
    on the client side, I pressed "Get Remote Object" button. Now, buttons
    like "Avg. Age" is pressed to retrieve the remote object's avg. age.
    After doing so, I pressed the "Destroy Remote Object" button on the
    server side. It destroys its exposed object and unregister its
    connection, named "server" by calling registerName:nil

    So, the client code receive the notification well, and destroy its local
    proxy.

    Now, because there is no exposed remote object, pressing "Get Remote
    Object" button on the client side should fail in obtaining the server's
    exposed object. But it retrieves something. The address is different
    from that obtained by the 1st trial.
    And whatever message, i.e. the one which is defined in a protocol, or
    the remote object  can handle, you send to the remote object, the remote
    object receives it successfully.

    Isn't weird? Is there something wrong with my code?

    Can anyone help me?

    Thank you.
  • On Aug 29, 2007, at 11:41 PM, JongAm Park wrote:
    > So, the client code receive the notification well, and destroy its
    > local proxy.
    > Now, because there is no exposed remote object, pressing "Get Remote
    > Object" button on the client side should fail in obtaining the
    > server's exposed object. But it retrieves something. The address is
    > different from that obtained by the 1st trial.
    > And whatever message, i.e. the one which is defined in a protocol,
    > or the remote object  can handle, you send to the remote object, the
    > remote object receives it successfully.

    I haven't studied the remote object issues for a while, but as I
    remember, last time I tried it, registerName: nevers really
    unregisters the server, though the documentation says so. Perhaps it's
    better to see if the vended server object is really released by your
    release call, or if it's still retained by somebody else.

    It's understandable that your client retrieves something after the
    server object is supposed to die, as what the client retrieves is a
    new proxy object that still points to the same vended server object.

    d.
  • Thank you very much for your comment.

    I checked it but it didn't seem to have such an object which hold the
    remote object/proxy object.
    One thing I guess is that it is held in a cache.

    Can it be a good idea to file this as a bug?
    At least the document is misleading as you mentioned that registerName:
    doesn't unregister what it registered.

    Thank you.

    Lukhnos D. Liu wrote:
    > On Aug 29, 2007, at 11:41 PM, JongAm Park wrote:
    >> So, the client code receive the notification well, and destroy its
    >> local proxy.
    >> Now, because there is no exposed remote object, pressing "Get Remote
    >> Object" button on the client side should fail in obtaining the
    >> server's exposed object. But it retrieves something. The address is
    >> different from that obtained by the 1st trial.
    >> And whatever message, i.e. the one which is defined in a protocol, or
    >> the remote object  can handle, you send to the remote object, the
    >> remote object receives it successfully.
    >
    > I haven't studied the remote object issues for a while, but as I
    > remember, last time I tried it, registerName: nevers really
    > unregisters the server, though the documentation says so. Perhaps it's
    > better to see if the vended server object is really released by your
    > release call, or if it's still retained by somebody else.
    >
    > It's understandable that your client retrieves something after the
    > server object is supposed to die, as what the client retrieves is a
    > new proxy object that still points to the same vended server object.
    >
    > d.
    >
    >
previous month august 2007 next month
MTWTFSS
    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31    
Go to today