blob: 1108428cb05f790c6ddeadf6dae66e33052e700f [file] [log] [blame]
Mark Slee77575e62007-09-24 19:24:53 +00001#import <Cocoa/Cocoa.h>
2#import "TSocketServer.h"
3#import "TNSFileHandleTransport.h"
4#import "TProtocol.h"
Mark Slee84406052007-11-20 01:39:25 +00005#import "TTransportException.h"
Mark Slee77575e62007-09-24 19:24:53 +00006
7
8@implementation TSocketServer
9
10- (id) initWithPort: (int) port
11 protocolFactory: (id <TProtocolFactory>) protocolFactory
12 processor: (id <TProcessor>) processor;
13{
14 self = [super init];
15
16 mInputProtocolFactory = [protocolFactory retain];
17 mOutputProtocolFactory = [protocolFactory retain];
18 mProcessor = [processor retain];
David Reiss0c90f6f2008-02-06 22:18:40 +000019
Mark Slee77575e62007-09-24 19:24:53 +000020 // create a socket
Mark Slee84406052007-11-20 01:39:25 +000021 mServerSocket = [[NSSocketPort alloc] initWithTCPPort: port];
22 // FIXME - move this separate start method and add method to close
23 // and cleanup any open ports
David Reiss0c90f6f2008-02-06 22:18:40 +000024
Mark Slee84406052007-11-20 01:39:25 +000025 if (mServerSocket == nil) {
26 NSLog(@"Unable to listen on TCP port %d", port);
27 } else {
28 NSLog(@"Listening on TCP port %d", port);
Mark Slee77575e62007-09-24 19:24:53 +000029
Mark Slee84406052007-11-20 01:39:25 +000030 // wrap it in a file handle so we can get messages from it
31 mSocketFileHandle = [[NSFileHandle alloc] initWithFileDescriptor: [mServerSocket socket]
32 closeOnDealloc: YES];
David Reiss0c90f6f2008-02-06 22:18:40 +000033
Mark Slee84406052007-11-20 01:39:25 +000034 // register for notifications of accepted incoming connections
David Reiss0c90f6f2008-02-06 22:18:40 +000035 [[NSNotificationCenter defaultCenter] addObserver: self
36 selector: @selector(connectionAccepted:)
Mark Slee84406052007-11-20 01:39:25 +000037 name: NSFileHandleConnectionAcceptedNotification
38 object: mSocketFileHandle];
David Reiss0c90f6f2008-02-06 22:18:40 +000039
Mark Slee84406052007-11-20 01:39:25 +000040 // tell socket to listen
41 [mSocketFileHandle acceptConnectionInBackgroundAndNotify];
42 }
David Reiss0c90f6f2008-02-06 22:18:40 +000043
Mark Slee77575e62007-09-24 19:24:53 +000044 return self;
45}
46
47
48- (void) dealloc {
49 [mInputProtocolFactory release];
50 [mOutputProtocolFactory release];
51 [mProcessor release];
52 [mSocketFileHandle release];
53 [mServerSocket release];
54 [super dealloc];
55}
56
57
Mark Slee84406052007-11-20 01:39:25 +000058- (void) connectionAccepted: (NSNotification *) aNotification
Mark Slee77575e62007-09-24 19:24:53 +000059{
60 NSFileHandle * socket = [[aNotification userInfo] objectForKey: NSFileHandleNotificationFileHandleItem];
David Reiss0c90f6f2008-02-06 22:18:40 +000061
Mark Slee77575e62007-09-24 19:24:53 +000062 // now that we have a client connected, spin off a thread to handle activity
63 [NSThread detachNewThreadSelector: @selector(handleClientConnection:)
64 toTarget: self
65 withObject: socket];
David Reiss0c90f6f2008-02-06 22:18:40 +000066
Mark Slee77575e62007-09-24 19:24:53 +000067 [[aNotification object] acceptConnectionInBackgroundAndNotify];
68}
69
70
71- (void) handleClientConnection: (NSFileHandle *) clientSocket
72{
73 NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
74
75 TNSFileHandleTransport * transport = [[TNSFileHandleTransport alloc] initWithFileHandle: clientSocket];
76
77 id <TProtocol> inProtocol = [mInputProtocolFactory newProtocolOnTransport: transport];
78 id <TProtocol> outProtocol = [mOutputProtocolFactory newProtocolOnTransport: transport];
David Reiss0c90f6f2008-02-06 22:18:40 +000079
Mark Slee84406052007-11-20 01:39:25 +000080 @try {
81 while ([mProcessor processOnInputProtocol: inProtocol outputProtocol: outProtocol]);
82 }
83 @catch (TTransportException * te) {
84 NSLog(@"%@", te);
85 }
David Reiss0c90f6f2008-02-06 22:18:40 +000086
Mark Slee77575e62007-09-24 19:24:53 +000087 [pool release];
88}
89
90
91
92@end
93
94
95