Fixed ios multiple sockets streams

This commit is contained in:
kitolog 2017-10-26 18:48:36 +03:00
parent 5f5b0264a1
commit 44dfa14566
3 changed files with 100 additions and 91 deletions

View File

@ -19,6 +19,11 @@
@interface SocketAdapter : NSObject <NSStreamDelegate> {
@public
CFReadStreamRef readStream1;
CFWriteStreamRef writeStream1;
NSInputStream *inputStream1;
NSOutputStream *outputStream1;
}
- (void)open:(NSString *)host port:(NSNumber*)port;

View File

@ -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

View File

@ -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 {