I've got a simple client & server application semi working with CocoaAsyncSocket. I can use the client to connect to the server, and can pass data back and forth between them and the delegate methods seem to fire correctly. My problem is that I can only send data back to a (AsyncSocket *) object that is passed to one of delegate methods. When accepting a connection I add the socket to an NSMutableArray, but later if I try to use the socket writing fails. So
[connectedSockets addObject:newSocket];
//then later
[[connectedSockets objectAtIndex:i] writeData:someData withTimeout:-1 tag:0];
doesn't work. Code is below for server and client. The initial communication does work, but when my notification gets called no data is sent, even though the NSLog statement tests the socket in the array and gets the proper IP Address & port #:
Server:
- (id)init
{
self = [super init];
if (self) {
listenSocket = [[AsyncSocket alloc] initWithDelegate:self];
[listenSocket setRunLoopModes:[NSArray arrayWithObject:NSRunLoopCommonModes]];
[listenSocket acceptOnPort:42381 error:nil];
connectedSockets = [[NSMutableArray alloc] init];
newNotificationDictArray = [[NSMutableArray alloc] init];
updateNotificationDictArray = [[NSMutableArray alloc] init];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(newJobNotification:)
name:@"NewJob"
object:nil];
}
return self;
}
-(void)onSocketDidDisconnect:(AsyncSocket *)sock
{
[connectedSockets removeObject:sock];
}
- (void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err
{
[connectedSockets removeObject:sock];
}
- (void)onSocket:(AsyncSocket *)sock didAcceptNewSocket:(AsyncSocket *)newSocket
{
[connectedSockets addObject:newSocket];
}
- (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port
{
if ([newNotificationDictArray count] > 0) {
NSMutableData *data = [[NSMutableData alloc] init];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
[archiver encodeObject:newNotificationDictArray forKey:@"DictArray"];
[archiver finishEncoding];
[archiver release];
[sock writeData:data withTimeout:-1 tag:0];
[data release];
}
[sock readDataWithTimeout:-1 tag:0];
}
- (void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag
{
[sock readDataWithTimeout:-1 tag:0];
}
- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
[sock readDataWithTimeout:-1 tag:0];
}
-(void) newJobNotification: (NSNotification *) notification
{
NSDictionary *dict = [notification userInfo];
[newNotificationDictArray addObject:dict];
[updateNotificationDictArray addObject:dict];
NSMutableData *updateData = [[NSMutableData alloc] init];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:updateData];
[archiver encodeObject:updateNotificationDictArray forKey:@"DictArray"];
[archiver finishEncoding]
[updateNotificationDictArray removeAllObjects];
[archiver release];
NSLog(@"Attempting to write to %@:%i", [[connectedSockets objectAtIndex:0] connectedHost], [[connectedSockets objectAtIndex:0] connectedPort])
[[connectedSockets objectAtIndex:0] writeData:updateData withTimeout:-1 tag:0];
}
and then the client:
- (id)init
{
self = [super init];
if (self) {
socket = [[AsyncSocket alloc] initWithDelegate:self];
}
return self;
}
-(void) connectToHost: (NSString *) address
{
}
-(BOOL)onSocketWillConnect:(AsyncSocket *)sock
{
[sock retain];
[socket readDataWithTimeout:-1 tag:0];
return YES;
}
-(void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port
{
NSLog(@"Did Connect on port %i", [sock connectedPort]);
}
-(void) disconnectFromRemoteHost
{
[socket disconnect];
}
-(void)onSocketDidDisconnect:(AsyncSocket *)sock
{
NSLog(@"Did Disconnect");
}
- (void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err
{
NSLog(@"Disconnect Error: %@", [err localizedDescription]);
}
- (void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag
{
[socket readDataWithTimeout:-1 tag:0];
}
- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
NSArray *dictArray = [[unarchiver decodeObjectForKey:@"DictArray"] retain];
[unarchiver finishDecoding];
[unarchiver release];
for (NSDictionary *dict in dictArray) {
if ([[dict objectForKey:@"Kind"] isEqualTo:@"New"])
[[NSNotificationCenter defaultCenter] postNotificationName:@"NewJob" object:self userInfo:dict];
else if ([[dict objectForKey:@"Kind"] isEqualTo:@"Update"])
[[NSNotificationCenter defaultCenter] postNotificationName:@"JobUpdate" object:self userInfo:dict];
}
[socket readDataWithTimeout:-1 tag:0];
}
Help me stackoverflow, you're my only hope!