blob: 97d8bae7b19376d4d3718d8171d9c1b3c4b3e6d1 [file] [log] [blame]
David Reissea2cba82009-03-30 21:35:00 +00001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
Mark Slee77575e62007-09-24 19:24:53 +000020#import <Cocoa/Cocoa.h>
21#import "TSocketServer.h"
22#import "TNSFileHandleTransport.h"
23#import "TProtocol.h"
Mark Slee84406052007-11-20 01:39:25 +000024#import "TTransportException.h"
Mark Slee77575e62007-09-24 19:24:53 +000025
26
27@implementation TSocketServer
28
29- (id) initWithPort: (int) port
30 protocolFactory: (id <TProtocolFactory>) protocolFactory
31 processor: (id <TProcessor>) processor;
32{
33 self = [super init];
34
35 mInputProtocolFactory = [protocolFactory retain];
36 mOutputProtocolFactory = [protocolFactory retain];
37 mProcessor = [processor retain];
David Reiss0c90f6f2008-02-06 22:18:40 +000038
Mark Slee77575e62007-09-24 19:24:53 +000039 // create a socket
Mark Slee84406052007-11-20 01:39:25 +000040 mServerSocket = [[NSSocketPort alloc] initWithTCPPort: port];
41 // FIXME - move this separate start method and add method to close
42 // and cleanup any open ports
David Reiss0c90f6f2008-02-06 22:18:40 +000043
Mark Slee84406052007-11-20 01:39:25 +000044 if (mServerSocket == nil) {
45 NSLog(@"Unable to listen on TCP port %d", port);
46 } else {
47 NSLog(@"Listening on TCP port %d", port);
Mark Slee77575e62007-09-24 19:24:53 +000048
Mark Slee84406052007-11-20 01:39:25 +000049 // wrap it in a file handle so we can get messages from it
50 mSocketFileHandle = [[NSFileHandle alloc] initWithFileDescriptor: [mServerSocket socket]
51 closeOnDealloc: YES];
David Reiss0c90f6f2008-02-06 22:18:40 +000052
Mark Slee84406052007-11-20 01:39:25 +000053 // register for notifications of accepted incoming connections
David Reiss0c90f6f2008-02-06 22:18:40 +000054 [[NSNotificationCenter defaultCenter] addObserver: self
55 selector: @selector(connectionAccepted:)
Mark Slee84406052007-11-20 01:39:25 +000056 name: NSFileHandleConnectionAcceptedNotification
57 object: mSocketFileHandle];
David Reiss0c90f6f2008-02-06 22:18:40 +000058
Mark Slee84406052007-11-20 01:39:25 +000059 // tell socket to listen
60 [mSocketFileHandle acceptConnectionInBackgroundAndNotify];
61 }
David Reiss0c90f6f2008-02-06 22:18:40 +000062
Mark Slee77575e62007-09-24 19:24:53 +000063 return self;
64}
65
66
67- (void) dealloc {
68 [mInputProtocolFactory release];
69 [mOutputProtocolFactory release];
70 [mProcessor release];
71 [mSocketFileHandle release];
72 [mServerSocket release];
73 [super dealloc];
74}
75
76
Mark Slee84406052007-11-20 01:39:25 +000077- (void) connectionAccepted: (NSNotification *) aNotification
Mark Slee77575e62007-09-24 19:24:53 +000078{
79 NSFileHandle * socket = [[aNotification userInfo] objectForKey: NSFileHandleNotificationFileHandleItem];
David Reiss0c90f6f2008-02-06 22:18:40 +000080
Mark Slee77575e62007-09-24 19:24:53 +000081 // now that we have a client connected, spin off a thread to handle activity
82 [NSThread detachNewThreadSelector: @selector(handleClientConnection:)
83 toTarget: self
84 withObject: socket];
David Reiss0c90f6f2008-02-06 22:18:40 +000085
Mark Slee77575e62007-09-24 19:24:53 +000086 [[aNotification object] acceptConnectionInBackgroundAndNotify];
87}
88
89
90- (void) handleClientConnection: (NSFileHandle *) clientSocket
91{
92 NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
93
94 TNSFileHandleTransport * transport = [[TNSFileHandleTransport alloc] initWithFileHandle: clientSocket];
95
96 id <TProtocol> inProtocol = [mInputProtocolFactory newProtocolOnTransport: transport];
97 id <TProtocol> outProtocol = [mOutputProtocolFactory newProtocolOnTransport: transport];
David Reiss0c90f6f2008-02-06 22:18:40 +000098
Mark Slee84406052007-11-20 01:39:25 +000099 @try {
100 while ([mProcessor processOnInputProtocol: inProtocol outputProtocol: outProtocol]);
101 }
102 @catch (TTransportException * te) {
103 NSLog(@"%@", te);
104 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000105
Mark Slee77575e62007-09-24 19:24:53 +0000106 [pool release];
107}
108
109
110
111@end
112
113
114