From 44dfa145668dd82e96661fd4c2bb826e0b3c359a Mon Sep 17 00:00:00 2001 From: kitolog Date: Thu, 26 Oct 2017 18:48:36 +0300 Subject: [PATCH] Fixed ios multiple sockets streams --- .../SocketsForCordova/Classes/SocketAdapter.h | 5 + .../SocketsForCordova/Classes/SocketAdapter.m | 96 ++++++++++--------- .../SocketsForCordova/Classes/SocketPlugin.m | 90 ++++++++--------- 3 files changed, 100 insertions(+), 91 deletions(-) diff --git a/src/ios/SocketsForCordova/Classes/SocketAdapter.h b/src/ios/SocketsForCordova/Classes/SocketAdapter.h index 860a11c..7b0c6e0 100644 --- a/src/ios/SocketsForCordova/Classes/SocketAdapter.h +++ b/src/ios/SocketsForCordova/Classes/SocketAdapter.h @@ -19,6 +19,11 @@ @interface SocketAdapter : NSObject { @public + CFReadStreamRef readStream1; + CFWriteStreamRef writeStream1; + + NSInputStream *inputStream1; + NSOutputStream *outputStream1; } - (void)open:(NSString *)host port:(NSNumber*)port; diff --git a/src/ios/SocketsForCordova/Classes/SocketAdapter.m b/src/ios/SocketsForCordova/Classes/SocketAdapter.m index 4d9f631..88522fe 100644 --- a/src/ios/SocketsForCordova/Classes/SocketAdapter.m +++ b/src/ios/SocketsForCordova/Classes/SocketAdapter.m @@ -35,36 +35,40 @@ int const WRITE_BUFFER_SIZE = 10 * 1024; - (void)open:(NSString *)host port:(NSNumber*)port { + CFReadStreamRef readStream2; + CFWriteStreamRef writeStream2; + + NSLog(@"Setting up connection to %@ : %@", host, [port stringValue]); - + if (![self isIp:host]) { host = [self resolveIp:host]; } - - CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, (__bridge CFStringRef)host, [port intValue], &readStream, &writeStream); - - CFReadStreamSetProperty(readStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue); - CFWriteStreamSetProperty(writeStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue); - - if(!CFWriteStreamOpen(writeStream) || !CFReadStreamOpen(readStream)) { - NSLog(@"Error, streams not open"); - + + CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, (__bridge CFStringRef)host, [port intValue], &readStream2, &writeStream2); + + CFReadStreamSetProperty(readStream2, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue); + CFWriteStreamSetProperty(writeStream2, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue); + + if(!CFWriteStreamOpen(writeStream2) || !CFReadStreamOpen(readStream2)) { + NSLog(@"Error, streams not open"); + @throw [NSException exceptionWithName:@"SocketException" reason:@"Cannot open streams." userInfo:nil]; - } - - inputStream = (__bridge NSInputStream *)readStream; - [inputStream setDelegate:self]; - [inputStream open]; - - outputStream = (__bridge NSOutputStream *)writeStream; - [outputStream open]; + } + + inputStream1 = (__bridge NSInputStream *)readStream2; + [inputStream1 setDelegate:self]; + [inputStream1 open]; + + outputStream1 = (__bridge NSOutputStream *)writeStream2; + [outputStream1 open]; [self performSelectorOnMainThread:@selector(runReadLoop) withObject:nil waitUntilDone:NO]; } -(BOOL)isIp:(NSString*) host { const char *utf8 = [host UTF8String]; - + // Check valid IPv4. struct in_addr dst; int success = inet_pton(AF_INET, utf8, &(dst.s_addr)); @@ -77,47 +81,47 @@ int const WRITE_BUFFER_SIZE = 10 * 1024; } -(NSString*)resolveIp:(NSString*) host { - + NSLog(@"Resolving host: %@", host); - + const char *buff = [host cStringUsingEncoding:NSUTF8StringEncoding]; struct hostent *host_entry = gethostbyname(buff); - + if(host_entry == NULL) { @throw [NSException exceptionWithName:@"NSException" reason:@"Cannot resolve hostname." userInfo:nil]; } - + char *hostCstring = inet_ntoa(*((struct in_addr *)host_entry->h_addr_list[0])); host = [NSString stringWithUTF8String:hostCstring]; NSLog(@"Resolved ip: %@", host); - + return host; } - (void)runReadLoop { - [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; + [inputStream1 scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; } - (void)shutdownWrite { NSLog(@"Shuting down write on socket."); - + [self closeOutputStream]; - - int socket = [self socknumForStream: inputStream]; + + int socket = [self socknumForStream: inputStream1]; shutdown(socket, 1); } - (void)closeInputStream { - [inputStream close]; - [inputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; - [inputStream setDelegate:nil]; - inputStream = nil; + [inputStream1 close]; + [inputStream1 removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; + [inputStream1 setDelegate:nil]; + inputStream1 = nil; } - (void)closeOutputStream { - [outputStream close]; - outputStream = nil; + [outputStream1 close]; + outputStream1 = nil; } -(int) socknumForStream: (NSStream *)stream @@ -134,7 +138,7 @@ int const WRITE_BUFFER_SIZE = 10 * 1024; } - (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)event { - + switch(event) { case NSStreamEventOpenCompleted: { self.openEventHandler(); @@ -142,14 +146,14 @@ int const WRITE_BUFFER_SIZE = 10 * 1024; break; } case NSStreamEventHasBytesAvailable: { - if(stream == inputStream) { + if(stream == inputStream1) { uint8_t buf[65535]; - long len = [inputStream read:buf maxLength:65535]; + long len = [inputStream1 read:buf maxLength:65535]; if(len > 0) { NSMutableArray *dataArray = [[NSMutableArray alloc] init]; for (long i = 0; i < len; i++) { - + [dataArray addObject:[NSNumber numberWithUnsignedChar:buf[i]]]; } self.dataConsumer(dataArray); @@ -158,10 +162,10 @@ int const WRITE_BUFFER_SIZE = 10 * 1024; break; } case NSStreamEventEndEncountered: { - - if(stream == inputStream) { + + if(stream == inputStream1) { [self closeInputStream]; - + self.closeEventHandler(FALSE); break; } @@ -169,7 +173,7 @@ int const WRITE_BUFFER_SIZE = 10 * 1024; case NSStreamEventErrorOccurred: { NSLog(@"Stream event error: %@", [[stream streamError] localizedDescription]); - + if (wasOpenned) { self.errorEventHandler([[stream streamError] localizedDescription]); self.closeEventHandler(TRUE); @@ -182,7 +186,7 @@ int const WRITE_BUFFER_SIZE = 10 * 1024; break; } default: { - + break; } } @@ -203,9 +207,9 @@ int const WRITE_BUFFER_SIZE = 10 * 1024; unsigned char byte = (unsigned char)[[dataArray objectAtIndex:(offset + i)] integerValue]; buf[i] = byte; } - NSInteger bytesWritten = [outputStream write:buf maxLength:length]; + NSInteger bytesWritten = [outputStream1 write:buf maxLength:length]; if (bytesWritten == -1) { - @throw [NSException exceptionWithName:@"SocketException" reason:[outputStream.streamError localizedDescription] userInfo:nil]; + @throw [NSException exceptionWithName:@"SocketException" reason:[outputStream1.streamError localizedDescription] userInfo:nil]; } if (bytesWritten != length) { [self writeSubarray:dataArray offset:(offset + bytesWritten) length:(length - bytesWritten)]; @@ -222,4 +226,4 @@ int const WRITE_BUFFER_SIZE = 10 * 1024; [self closeInputStream]; } -@end +@end \ No newline at end of file diff --git a/src/ios/SocketsForCordova/Classes/SocketPlugin.m b/src/ios/SocketsForCordova/Classes/SocketPlugin.m index 53b4667..f09184b 100644 --- a/src/ios/SocketsForCordova/Classes/SocketPlugin.m +++ b/src/ios/SocketsForCordova/Classes/SocketPlugin.m @@ -24,35 +24,35 @@ - (void) open : (CDVInvokedUrlCommand*) command { - NSString *socketKey = [command.arguments objectAtIndex:0]; - NSString *host = [command.arguments objectAtIndex:1]; - NSNumber *port = [command.arguments objectAtIndex:2]; - + NSString *socketKey = [command.arguments objectAtIndex:0]; + NSString *host = [command.arguments objectAtIndex:1]; + NSNumber *port = [command.arguments objectAtIndex:2]; + if (socketAdapters == nil) { - self->socketAdapters = [[NSMutableDictionary alloc] init]; - } - - __block SocketAdapter* socketAdapter = [[SocketAdapter alloc] init]; + self->socketAdapters = [[NSMutableDictionary alloc] init]; + } + + __block SocketAdapter* socketAdapter = [[SocketAdapter alloc] init]; socketAdapter.openEventHandler = ^ void () { [self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_OK] callbackId:command.callbackId]; - + [self->socketAdapters setObject:socketAdapter forKey:socketKey]; - + socketAdapter = nil; }; socketAdapter.openErrorEventHandler = ^ void (NSString *error){ [self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:error] callbackId:command.callbackId]; - + socketAdapter = nil; }; - socketAdapter.errorEventHandler = ^ void (NSString *error){ + socketAdapter.errorEventHandler = ^ void (NSString *error){ NSMutableDictionary *errorDictionaryData = [[NSMutableDictionary alloc] init]; [errorDictionaryData setObject:@"Error" forKey:@"type"]; [errorDictionaryData setObject:error forKey:@"errorMessage"]; [errorDictionaryData setObject:socketKey forKey:@"socketKey"]; - + [self dispatchEventWithDictionary:errorDictionaryData]; }; socketAdapter.dataConsumer = ^ void (NSArray* dataArray) { @@ -60,7 +60,7 @@ [dataDictionary setObject:@"DataReceived" forKey:@"type"]; [dataDictionary setObject:dataArray forKey:@"data"]; [dataDictionary setObject:socketKey forKey:@"socketKey"]; - + [self dispatchEventWithDictionary:dataDictionary]; }; socketAdapter.closeEventHandler = ^ void (BOOL hasErrors) { @@ -68,34 +68,34 @@ [closeDictionaryData setObject:@"Close" forKey:@"type"]; [closeDictionaryData setObject:(hasErrors == TRUE ? @"true": @"false") forKey:@"hasError"]; [closeDictionaryData setObject:socketKey forKey:@"socketKey"]; - + [self dispatchEventWithDictionary:closeDictionaryData]; - + [self removeSocketAdapter:socketKey]; }; - + [self.commandDelegate runInBackground:^{ @try { [socketAdapter open:host port:port]; } @catch (NSException *e) { [self.commandDelegate - sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:e.reason] - callbackId:command.callbackId]; - + sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:e.reason] + callbackId:command.callbackId]; + socketAdapter = nil; } }]; } - (void) write:(CDVInvokedUrlCommand *) command { - + NSString* socketKey = [command.arguments objectAtIndex:0]; NSArray *data = [command.arguments objectAtIndex:1]; - + SocketAdapter *socket = [self getSocketAdapter:socketKey]; - - [self.commandDelegate runInBackground:^{ + + [self.commandDelegate runInBackground:^{ @try { [socket write:data]; [self.commandDelegate @@ -111,32 +111,32 @@ } - (void) shutdownWrite:(CDVInvokedUrlCommand *) command { - + NSString* socketKey = [command.arguments objectAtIndex:0]; - - SocketAdapter *socket = [self getSocketAdapter:socketKey]; - + + SocketAdapter *socket = [self getSocketAdapter:socketKey]; + [self.commandDelegate runInBackground:^{ @try { [socket shutdownWrite]; [self.commandDelegate - sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_OK] - callbackId:command.callbackId]; + sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_OK] + callbackId:command.callbackId]; } @catch (NSException *e) { [self.commandDelegate - sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:e.reason] - callbackId:command.callbackId]; + sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:e.reason] + callbackId:command.callbackId]; } }]; } - (void) close:(CDVInvokedUrlCommand *) command { - + NSString* socketKey = [command.arguments objectAtIndex:0]; - - SocketAdapter *socket = [self getSocketAdapter:socketKey]; - + + SocketAdapter *socket = [self getSocketAdapter:socketKey]; + [self.commandDelegate runInBackground:^{ @try { [socket close]; @@ -156,13 +156,13 @@ } - (SocketAdapter*) getSocketAdapter: (NSString*) socketKey { - SocketAdapter* socketAdapter = [self->socketAdapters objectForKey:socketKey]; - if (socketAdapter == nil) { - NSString *exceptionReason = [NSString stringWithFormat:@"Cannot find socketKey: %@. Connection is probably closed.", socketKey]; - - @throw [NSException exceptionWithName:@"IllegalArgumentException" reason:exceptionReason userInfo:nil]; - } - return socketAdapter; + SocketAdapter* socketAdapter = [self->socketAdapters objectForKey:socketKey]; + if (socketAdapter == nil) { + NSString *exceptionReason = [NSString stringWithFormat:@"Cannot find socketKey: %@. Connection is probably closed.", socketKey]; + + @throw [NSException exceptionWithName:@"IllegalArgumentException" reason:exceptionReason userInfo:nil]; + } + return socketAdapter; } - (void) removeSocketAdapter: (NSString*) socketKey { @@ -171,8 +171,8 @@ } - (BOOL) socketAdapterExists: (NSString*) socketKey { - SocketAdapter* socketAdapter = [self->socketAdapters objectForKey:socketKey]; - return socketAdapter != nil; + SocketAdapter* socketAdapter = [self->socketAdapters objectForKey:socketKey]; + return socketAdapter != nil; } - (void) dispatchEventWithDictionary: (NSDictionary*) dictionary {