Fixed ios api
This commit is contained in:
parent
d13b37b960
commit
5083cfe79b
@ -1,19 +1,19 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface SocketAdapter : NSObject <NSStreamDelegate> {
|
||||
@public
|
||||
}
|
||||
|
||||
- (void)connect:(NSString *)host port:(NSNumber*)port;
|
||||
- (void)write:(NSArray *)dataArray;
|
||||
- (void)shutdownWrite;
|
||||
- (void)close;
|
||||
- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)event;
|
||||
|
||||
@property (copy) void (^openEventHandler)();
|
||||
@property (copy) void (^openErrorEventHandler)(NSString*);
|
||||
@property (copy) void (^dataConsumer)(NSArray*);
|
||||
@property (copy) void (^closeEventHandler)(BOOL);
|
||||
@property (copy) void (^errorEventHandler)(NSString*);
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface SocketAdapter : NSObject <NSStreamDelegate> {
|
||||
@public
|
||||
}
|
||||
|
||||
- (void)open:(NSString *)host port:(NSNumber*)port;
|
||||
- (void)write:(NSArray *)dataArray;
|
||||
- (void)shutdownWrite;
|
||||
- (void)close;
|
||||
- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)event;
|
||||
|
||||
@property (copy) void (^openEventHandler)();
|
||||
@property (copy) void (^openErrorEventHandler)(NSString*);
|
||||
@property (copy) void (^dataConsumer)(NSArray*);
|
||||
@property (copy) void (^closeEventHandler)(BOOL);
|
||||
@property (copy) void (^errorEventHandler)(NSString*);
|
||||
|
||||
@end
|
@ -1,189 +1,192 @@
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <arpa/inet.h>
|
||||
#import "SocketAdapter.h"
|
||||
|
||||
CFReadStreamRef readStream;
|
||||
CFWriteStreamRef writeStream;
|
||||
|
||||
NSInputStream *inputStream;
|
||||
NSOutputStream *outputStream;
|
||||
|
||||
BOOL wasOpenned = FALSE;
|
||||
|
||||
@implementation SocketAdapter
|
||||
|
||||
- (void)connect:(NSString *)host port:(NSNumber*)port {
|
||||
|
||||
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");
|
||||
|
||||
@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];
|
||||
|
||||
[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));
|
||||
if (success != 1) {
|
||||
// Check valid IPv6.
|
||||
struct in6_addr dst6;
|
||||
success = inet_pton(AF_INET6, utf8, &dst6);
|
||||
}
|
||||
return (success == 1);
|
||||
}
|
||||
|
||||
-(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];
|
||||
}
|
||||
|
||||
- (void)shutdownWrite {
|
||||
NSLog(@"Shuting down write on socket.");
|
||||
|
||||
[self closeOutputStream];
|
||||
|
||||
int socket = [self socknumForStream: inputStream];
|
||||
shutdown(socket, 1);
|
||||
}
|
||||
|
||||
- (void)closeInputStream {
|
||||
[inputStream close];
|
||||
[inputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
|
||||
[inputStream setDelegate:nil];
|
||||
inputStream = nil;
|
||||
}
|
||||
|
||||
- (void)closeOutputStream {
|
||||
[outputStream close];
|
||||
outputStream = nil;
|
||||
}
|
||||
|
||||
-(int) socknumForStream: (NSStream *)stream
|
||||
{
|
||||
int sock = -1;
|
||||
NSData *sockObj = [stream propertyForKey:
|
||||
(__bridge NSString *)kCFStreamPropertySocketNativeHandle];
|
||||
if ([sockObj isKindOfClass:[NSData class]] &&
|
||||
([sockObj length] == sizeof(int)) ) {
|
||||
const int *sockptr = (const int *)[sockObj bytes];
|
||||
sock = *sockptr;
|
||||
}
|
||||
return sock;
|
||||
}
|
||||
|
||||
- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)event {
|
||||
|
||||
switch(event) {
|
||||
case NSStreamEventOpenCompleted: {
|
||||
self.openEventHandler();
|
||||
wasOpenned = TRUE;
|
||||
break;
|
||||
}
|
||||
case NSStreamEventHasBytesAvailable: {
|
||||
if(stream == inputStream) {
|
||||
uint8_t buf[65535];
|
||||
long len = [inputStream 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);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NSStreamEventEndEncountered: {
|
||||
|
||||
if(stream == inputStream) {
|
||||
[self closeInputStream];
|
||||
|
||||
self.closeEventHandler(FALSE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
case NSStreamEventErrorOccurred:
|
||||
{
|
||||
NSLog(@"Stream event error: %@", [[stream streamError] localizedDescription]);
|
||||
|
||||
[self close];
|
||||
|
||||
if (wasOpenned) {
|
||||
self.errorEventHandler([[stream streamError] localizedDescription]);
|
||||
self.closeEventHandler(TRUE);
|
||||
}
|
||||
else {
|
||||
self.errorEventHandler([[stream streamError] localizedDescription]);
|
||||
self.openErrorEventHandler([[stream streamError] localizedDescription]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)write:(NSArray *)dataArray {
|
||||
uint8_t buf[dataArray.count];
|
||||
for (int i = 0; i < dataArray.count; i++) {
|
||||
buf[i] = (unsigned char)[[dataArray objectAtIndex:i] integerValue];
|
||||
}
|
||||
NSInteger bytesWritten = [outputStream write:buf maxLength:dataArray.count];
|
||||
if (bytesWritten == -1) {
|
||||
@throw [NSException exceptionWithName:@"SocketException" reason:[outputStream.streamError localizedDescription] userInfo:nil];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)close {
|
||||
self.closeEventHandler(FALSE);
|
||||
[self closeOutputStream];
|
||||
[self closeInputStream];
|
||||
}
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <arpa/inet.h>
|
||||
#import "SocketAdapter.h"
|
||||
|
||||
CFReadStreamRef readStream;
|
||||
CFWriteStreamRef writeStream;
|
||||
|
||||
NSInputStream *inputStream;
|
||||
NSOutputStream *outputStream;
|
||||
|
||||
BOOL wasOpenned = FALSE;
|
||||
|
||||
@implementation SocketAdapter
|
||||
|
||||
- (void)open:(NSString *)host port:(NSNumber*)port {
|
||||
|
||||
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");
|
||||
|
||||
@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];
|
||||
|
||||
[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));
|
||||
if (success != 1) {
|
||||
// Check valid IPv6.
|
||||
struct in6_addr dst6;
|
||||
success = inet_pton(AF_INET6, utf8, &dst6);
|
||||
}
|
||||
return (success == 1);
|
||||
}
|
||||
|
||||
-(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];
|
||||
}
|
||||
|
||||
- (void)shutdownWrite {
|
||||
NSLog(@"Shuting down write on socket.");
|
||||
|
||||
[self closeOutputStream];
|
||||
|
||||
int socket = [self socknumForStream: inputStream];
|
||||
shutdown(socket, 1);
|
||||
}
|
||||
|
||||
- (void)closeInputStream {
|
||||
[inputStream close];
|
||||
[inputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
|
||||
[inputStream setDelegate:nil];
|
||||
inputStream = nil;
|
||||
}
|
||||
|
||||
- (void)closeOutputStream {
|
||||
[outputStream close];
|
||||
outputStream = nil;
|
||||
}
|
||||
|
||||
-(int) socknumForStream: (NSStream *)stream
|
||||
{
|
||||
int sock = -1;
|
||||
NSData *sockObj = [stream propertyForKey:
|
||||
(__bridge NSString *)kCFStreamPropertySocketNativeHandle];
|
||||
if ([sockObj isKindOfClass:[NSData class]] &&
|
||||
([sockObj length] == sizeof(int)) ) {
|
||||
const int *sockptr = (const int *)[sockObj bytes];
|
||||
sock = *sockptr;
|
||||
}
|
||||
return sock;
|
||||
}
|
||||
|
||||
- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)event {
|
||||
|
||||
switch(event) {
|
||||
case NSStreamEventOpenCompleted: {
|
||||
self.openEventHandler();
|
||||
wasOpenned = TRUE;
|
||||
break;
|
||||
}
|
||||
case NSStreamEventHasBytesAvailable: {
|
||||
if(stream == inputStream) {
|
||||
uint8_t buf[65535];
|
||||
long len = [inputStream 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);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NSStreamEventEndEncountered: {
|
||||
|
||||
if(stream == inputStream) {
|
||||
[self closeInputStream];
|
||||
|
||||
self.closeEventHandler(FALSE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
case NSStreamEventErrorOccurred:
|
||||
{
|
||||
NSLog(@"Stream event error: %@", [[stream streamError] localizedDescription]);
|
||||
|
||||
if (wasOpenned) {
|
||||
self.errorEventHandler([[stream streamError] localizedDescription]);
|
||||
self.closeEventHandler(TRUE);
|
||||
}
|
||||
else {
|
||||
self.errorEventHandler([[stream streamError] localizedDescription]);
|
||||
self.openErrorEventHandler([[stream streamError] localizedDescription]);
|
||||
}
|
||||
//[self closeStreams];
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)write:(NSArray *)dataArray {
|
||||
uint8_t buf[dataArray.count];
|
||||
for (int i = 0; i < dataArray.count; i++) {
|
||||
buf[i] = (unsigned char)[[dataArray objectAtIndex:i] integerValue];
|
||||
}
|
||||
NSInteger bytesWritten = [outputStream write:buf maxLength:dataArray.count];
|
||||
if (bytesWritten == -1) {
|
||||
@throw [NSException exceptionWithName:@"SocketException" reason:[outputStream.streamError localizedDescription] userInfo:nil];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)close {
|
||||
self.closeEventHandler(FALSE);
|
||||
[self closeStreams];
|
||||
}
|
||||
|
||||
- (void)closeStreams {
|
||||
[self closeOutputStream];
|
||||
[self closeInputStream];
|
||||
}
|
||||
|
||||
@end
|
@ -1,12 +1,12 @@
|
||||
#import <Cordova/CDV.h>
|
||||
|
||||
@interface SocketPlugin : CDVPlugin {
|
||||
NSMutableDictionary *socketAdapters;
|
||||
}
|
||||
|
||||
-(void) connect: (CDVInvokedUrlCommand *) command;
|
||||
-(void) write: (CDVInvokedUrlCommand *) command;
|
||||
-(void) close: (CDVInvokedUrlCommand *) command;
|
||||
-(void) setOptions: (CDVInvokedUrlCommand *) command;
|
||||
|
||||
#import <Cordova/CDV.h>
|
||||
|
||||
@interface SocketPlugin : CDVPlugin {
|
||||
NSMutableDictionary *socketAdapters;
|
||||
}
|
||||
|
||||
-(void) open: (CDVInvokedUrlCommand *) command;
|
||||
-(void) write: (CDVInvokedUrlCommand *) command;
|
||||
-(void) close: (CDVInvokedUrlCommand *) command;
|
||||
-(void) setOptions: (CDVInvokedUrlCommand *) command;
|
||||
|
||||
@end
|
@ -1,173 +1,173 @@
|
||||
#import "SocketPlugin.h"
|
||||
#import "SocketAdapter.h"
|
||||
#import <cordova/CDV.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@implementation SocketPlugin : CDVPlugin
|
||||
|
||||
- (void) connect : (CDVInvokedUrlCommand*) command {
|
||||
|
||||
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];
|
||||
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){
|
||||
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) {
|
||||
NSMutableDictionary *dataDictionary = [[NSMutableDictionary alloc] init];
|
||||
[dataDictionary setObject:@"DataReceived" forKey:@"type"];
|
||||
[dataDictionary setObject:dataArray forKey:@"data"];
|
||||
[dataDictionary setObject:socketKey forKey:@"socketKey"];
|
||||
|
||||
[self dispatchEventWithDictionary:dataDictionary];
|
||||
};
|
||||
socketAdapter.closeEventHandler = ^ void (BOOL hasErrors) {
|
||||
NSMutableDictionary *closeDictionaryData = [[NSMutableDictionary alloc] init];
|
||||
[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 connect:host port:port];
|
||||
}
|
||||
@catch (NSException *e) {
|
||||
[self.commandDelegate
|
||||
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:^{
|
||||
@try {
|
||||
[socket write:data];
|
||||
[self.commandDelegate
|
||||
sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_OK]
|
||||
callbackId:command.callbackId];
|
||||
}
|
||||
@catch (NSException *e) {
|
||||
[self.commandDelegate
|
||||
sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:e.reason]
|
||||
callbackId:command.callbackId];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void) shutdownWrite:(CDVInvokedUrlCommand *) command {
|
||||
|
||||
NSString* socketKey = [command.arguments objectAtIndex:0];
|
||||
|
||||
SocketAdapter *socket = [self getSocketAdapter:socketKey];
|
||||
|
||||
[self.commandDelegate runInBackground:^{
|
||||
@try {
|
||||
[socket shutdownWrite];
|
||||
[self.commandDelegate
|
||||
sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_OK]
|
||||
callbackId:command.callbackId];
|
||||
}
|
||||
@catch (NSException *e) {
|
||||
[self.commandDelegate
|
||||
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];
|
||||
|
||||
[self.commandDelegate runInBackground:^{
|
||||
@try {
|
||||
[socket close];
|
||||
[self.commandDelegate
|
||||
sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_OK]
|
||||
callbackId:command.callbackId];
|
||||
}
|
||||
@catch (NSException *e) {
|
||||
[self.commandDelegate
|
||||
sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:e.reason]
|
||||
callbackId:command.callbackId];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void) setOptions: (CDVInvokedUrlCommand *) command {
|
||||
}
|
||||
|
||||
- (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;
|
||||
}
|
||||
|
||||
- (void) removeSocketAdapter: (NSString*) socketKey {
|
||||
NSLog(@"Removing socket adapter from storage.");
|
||||
[self->socketAdapters removeObjectForKey:socketKey];
|
||||
}
|
||||
|
||||
- (BOOL) socketAdapterExists: (NSString*) socketKey {
|
||||
SocketAdapter* socketAdapter = [self->socketAdapters objectForKey:socketKey];
|
||||
return socketAdapter != nil;
|
||||
}
|
||||
|
||||
- (void) dispatchEventWithDictionary: (NSDictionary*) dictionary {
|
||||
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictionary options:0 error:nil];
|
||||
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
|
||||
|
||||
[self dispatchEvent:jsonString];
|
||||
}
|
||||
|
||||
- (void) dispatchEvent: (NSString *) jsonEventString {
|
||||
NSString *jsToEval = [NSString stringWithFormat : @"window.Socket.dispatchEvent(%@);", jsonEventString];
|
||||
[self.commandDelegate evalJs:jsToEval];
|
||||
}
|
||||
|
||||
#import "SocketPlugin.h"
|
||||
#import "SocketAdapter.h"
|
||||
#import <cordova/CDV.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@implementation SocketPlugin : CDVPlugin
|
||||
|
||||
- (void) open : (CDVInvokedUrlCommand*) command {
|
||||
|
||||
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];
|
||||
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){
|
||||
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) {
|
||||
NSMutableDictionary *dataDictionary = [[NSMutableDictionary alloc] init];
|
||||
[dataDictionary setObject:@"DataReceived" forKey:@"type"];
|
||||
[dataDictionary setObject:dataArray forKey:@"data"];
|
||||
[dataDictionary setObject:socketKey forKey:@"socketKey"];
|
||||
|
||||
[self dispatchEventWithDictionary:dataDictionary];
|
||||
};
|
||||
socketAdapter.closeEventHandler = ^ void (BOOL hasErrors) {
|
||||
NSMutableDictionary *closeDictionaryData = [[NSMutableDictionary alloc] init];
|
||||
[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];
|
||||
|
||||
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:^{
|
||||
@try {
|
||||
[socket write:data];
|
||||
[self.commandDelegate
|
||||
sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_OK]
|
||||
callbackId:command.callbackId];
|
||||
}
|
||||
@catch (NSException *e) {
|
||||
[self.commandDelegate
|
||||
sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:e.reason]
|
||||
callbackId:command.callbackId];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void) shutdownWrite:(CDVInvokedUrlCommand *) command {
|
||||
|
||||
NSString* socketKey = [command.arguments objectAtIndex:0];
|
||||
|
||||
SocketAdapter *socket = [self getSocketAdapter:socketKey];
|
||||
|
||||
[self.commandDelegate runInBackground:^{
|
||||
@try {
|
||||
[socket shutdownWrite];
|
||||
[self.commandDelegate
|
||||
sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_OK]
|
||||
callbackId:command.callbackId];
|
||||
}
|
||||
@catch (NSException *e) {
|
||||
[self.commandDelegate
|
||||
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];
|
||||
|
||||
[self.commandDelegate runInBackground:^{
|
||||
@try {
|
||||
[socket close];
|
||||
[self.commandDelegate
|
||||
sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_OK]
|
||||
callbackId:command.callbackId];
|
||||
}
|
||||
@catch (NSException *e) {
|
||||
[self.commandDelegate
|
||||
sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:e.reason]
|
||||
callbackId:command.callbackId];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void) setOptions: (CDVInvokedUrlCommand *) command {
|
||||
}
|
||||
|
||||
- (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;
|
||||
}
|
||||
|
||||
- (void) removeSocketAdapter: (NSString*) socketKey {
|
||||
NSLog(@"Removing socket adapter from storage.");
|
||||
[self->socketAdapters removeObjectForKey:socketKey];
|
||||
}
|
||||
|
||||
- (BOOL) socketAdapterExists: (NSString*) socketKey {
|
||||
SocketAdapter* socketAdapter = [self->socketAdapters objectForKey:socketKey];
|
||||
return socketAdapter != nil;
|
||||
}
|
||||
|
||||
- (void) dispatchEventWithDictionary: (NSDictionary*) dictionary {
|
||||
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictionary options:0 error:nil];
|
||||
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
|
||||
|
||||
[self dispatchEvent:jsonString];
|
||||
}
|
||||
|
||||
- (void) dispatchEvent: (NSString *) jsonEventString {
|
||||
NSString *jsToEval = [NSString stringWithFormat : @"window.Socket.dispatchEvent(%@);", jsonEventString];
|
||||
[self.commandDelegate evalJs:jsToEval];
|
||||
}
|
||||
|
||||
@end
|
Loading…
Reference in New Issue
Block a user