home *** CD-ROM | disk | FTP | other *** search
- /* ChatController by Andrew Loewenstern (andrew@cubetech.com).*/
- /* This is a really simple */
- /* class that clearly shows you how to implement Distributed Objects */
- /* in a NeXTSTEP application. This example is totally free, and */
- /* there is no warranty. If you have questions about it, send me */
- /* some mail at andrew@cubetech.com. */
-
- #import "ChatController.h"
- #import <remote/NXProxy.h>
-
- @implementation ChatController
-
- - getHostName /* gets the host of the server app */
- {
- [NXApp runModalFor:[hostName window]];
- [[hostName window] close];
- return self;
- }
-
- - appDidInit:sender
- {
- NXConnection *conn;
-
- [self getHostName]; /* get the host of the server */
-
- /* try to connect to server */
- server = [NXConnection connectToName:"ChatServer" onHost:[hostName
- stringValue]];
- if(!server) /* we must be the server */
- {
- /* allocate the client list */
- clients = [[List allocFromZone:[self zone]] init];
- /* register ourselves */
- conn = [NXConnection registerRoot:self withName:"ChatServer"];
- [[conversation window] setTitle:"ChatServer"];
- server = self; /* messages we send to the server will */
- /* now go to us... */
- weAreServer = YES;
- }
- else /* we must be the client */
- {
- /* Get the connection for the server */
- conn = [server connectionForProxy];
- /* tell the runtime system that the */
- /* server responds to the Chat */
- /* protocol */
- [server setProtocolForProxy:@protocol(Chat)];
-
- weAreServer = NO;
- [server checkIn:self]; /* check in with the server */
- }
- /* we want to know if either the */
- /* server or the clients die... */
- [conn registerForInvalidationNotification:self];
- [conn runFromAppKit]; /* handle messages in the main event */
- /* loop */
- [entry selectText:self];
- return self;
- }
-
- - checkIn:
- sender
- {
- if(weAreServer)
- {
- /* stuff the client into the list so */
- /* we can send messages to it...*/
- [clients addObjectIfAbsent:sender];
- /* and tell the runtime system that */
- /* the client implements the Chat */
- /* protocol */
- [sender setProtocolForProxy:@protocol(Chat)];
- }
- return self;
- }
-
- - checkOut:
- sender
- {
- if(weAreServer)
- [clients removeObject:sender]; /* remove the client so we don't */
- /* send messages to it anymore */
- return self;
- }
-
-
- /* acceptMessage:from: is sent by the */
- /* server to every client. It returns */
- /* void so the server does not wait */
- /* for each client to accept the */
- /* message and return...*/
-
- - (void) acceptMessage:(in char *)message from:(in char *)name
- {
- int i;
- char *comp = NXZoneMalloc([self zone], strlen(name) +
- strlen(message) + 4);
-
- /* create the string to put in the */
- /* conversation window */
- sprintf(comp, "%s: %s\n", name, message);
-
- /* then select the very last line, */
- /* replace the selection with the */
- /* string, select the last line again, */
- /* and scroll it till it's visible */
- [conversation setSel:[conversation textLength] :[conversation
- textLength]];
- [conversation replaceSel:(const char *)comp];
- [conversation setSel:[conversation textLength] :[conversation
- textLength]];
- [conversation scrollSelToVisible];
-
- NXZoneFree([self zone], comp); /* free the string */
-
-
- /* for each client, we send the same */
- /* acceptMesage:from: message. Each */
- /* client will recieve it and display */
- /* the mesage */
- if(weAreServer)
- {
- for(i = 0; i < [clients count]; i++)
- [[clients objectAt:i] acceptMessage:message from:name];
- }
- }
-
-
- - senderIsInvalid:
- sender /* we will recieve this message if the */
- /* server dies, or if a client dies */
- /* (if we are the server */
- {
- if(weAreServer) /* then remove the client */
- [self checkOut:sender];
- else /* if there's no server, then we die */
- [NXApp terminate:self];
-
- return self;
- }
-
- - send:sender
- {
- /* send the message to the server! */
- /* It's as simple as this! */
- [server acceptMessage:[entry stringValue] from:getlogin()];
- [entry selectText:self];
- return self;
- }
-
- - appWillTerminate:
- sender
- {
- /* if we are a client, we should tell */
- /* the server not to send us messages. */
- /* Although the server will get a */
- /* senderIsInvalid message, it's */
- /* better to make sure the server */
- /* doesn't try to contact us after we */
- /* no longer exist... */
- if(!weAreServer)
- [server checkOut:self];
- return self;
- }
- @end
-