Refactor the UdpSockets module _clients array to be a member variable.
Make the UdpSocketClient's delegate a weak reference.
remove reload notificaiton, and rely on dealloc to close all open sockets.
This commit is contained in:
Andy Prock 2015-12-21 19:45:38 -08:00
parent 641b9d770e
commit e8050d3fe8
4 changed files with 24 additions and 45 deletions

View File

@ -38,6 +38,7 @@ typedef enum RCTUDPError RCTUDPError;
@property (nonatomic, retain) NSString* id; @property (nonatomic, retain) NSString* id;
@property (nonatomic, retain) NSString* host; @property (nonatomic, retain) NSString* host;
@property (nonatomic) u_int16_t port; @property (nonatomic) u_int16_t port;
@property (nonatomic, weak) id<SocketClientDelegate> clientDelegate;
///--------------------------------------------------------------------------------------- ///---------------------------------------------------------------------------------------
/// @name Class Methods /// @name Class Methods

View File

@ -20,7 +20,6 @@ NSString *const RCTUDPErrorDomain = @"RCTUDPErrorDomain";
uint16_t _port; uint16_t _port;
NSString* _address; NSString* _address;
GCDAsyncUdpSocket *_udpSocket; GCDAsyncUdpSocket *_udpSocket;
id<SocketClientDelegate> _clientDelegate;
NSMutableDictionary<NSNumber *, RCTResponseSenderBlock> *_pendingSends; NSMutableDictionary<NSNumber *, RCTResponseSenderBlock> *_pendingSends;
NSLock *_lock; NSLock *_lock;
long tag; long tag;

View File

@ -16,6 +16,4 @@
@interface UdpSockets : NSObject<SocketClientDelegate, RCTBridgeModule> @interface UdpSockets : NSObject<SocketClientDelegate, RCTBridgeModule>
+(NSMutableDictionary<NSNumber *, UdpSocketClient *> *)clients;
@end @end

View File

@ -15,49 +15,39 @@
#import "UdpSocketClient.h" #import "UdpSocketClient.h"
@implementation UdpSockets @implementation UdpSockets
{
NSMutableDictionary<NSNumber *, UdpSocketClient *> *_clients;
}
RCT_EXPORT_MODULE() RCT_EXPORT_MODULE()
@synthesize bridge = _bridge; @synthesize bridge = _bridge;
+ (void) initialize { - (void)dealloc
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(closeAllSockets)
name:RCTReloadNotification
object:nil];
}
+(NSMutableDictionary*) clients
{ {
static NSMutableDictionary* c = nil; for (NSNumber *cId in _clients.allKeys) {
[self closeClient:cId callback:nil];
static dispatch_once_t oncePredicate; }
dispatch_once(&oncePredicate, ^{
c = [[NSMutableDictionary alloc] init];
});
return c;
} }
RCT_EXPORT_METHOD(createSocket:(nonnull NSNumber*)cId withOptions:(NSDictionary*)options) RCT_EXPORT_METHOD(createSocket:(nonnull NSNumber*)cId withOptions:(NSDictionary*)options)
{ {
// if (!UdpSockets._clients) UdpSockets._clients = [[NSMutableDictionary alloc] init];
NSMutableDictionary<NSNumber *, UdpSocketClient *> *_clients = [UdpSockets clients];
if (!cId) { if (!cId) {
RCTLogError(@"%@.createSocket called with nil id parameter.", [self class]); RCTLogError(@"%@.createSocket called with nil id parameter.", [self class]);
return; return;
} }
UdpSocketClient *client = [_clients objectForKey:cId]; if (!_clients) {
if (client) { _clients = [NSMutableDictionary new];
}
if (_clients[cId]) {
RCTLogError(@"%@.createSocket called twice with the same id.", [self class]); RCTLogError(@"%@.createSocket called twice with the same id.", [self class]);
return; return;
} }
client = [UdpSocketClient socketClientWithConfig:self]; _clients[cId] = [UdpSocketClient socketClientWithConfig:self];
[_clients setObject:client forKey:cId];
} }
RCT_EXPORT_METHOD(bind:(nonnull NSNumber*)cId RCT_EXPORT_METHOD(bind:(nonnull NSNumber*)cId
@ -65,7 +55,7 @@ RCT_EXPORT_METHOD(bind:(nonnull NSNumber*)cId
address:(NSString *)address address:(NSString *)address
callback:(RCTResponseSenderBlock)callback) callback:(RCTResponseSenderBlock)callback)
{ {
UdpSocketClient* client = [UdpSockets findClient:cId callback:callback]; UdpSocketClient* client = [self findClient:cId callback:callback];
if (!client) return; if (!client) return;
NSError *error = nil; NSError *error = nil;
@ -84,7 +74,7 @@ RCT_EXPORT_METHOD(send:(nonnull NSNumber*)cId
port:(int)port port:(int)port
address:(NSString*)address address:(NSString*)address
callback:(RCTResponseSenderBlock)callback) { callback:(RCTResponseSenderBlock)callback) {
UdpSocketClient* client = [UdpSockets findClient:cId callback:callback]; UdpSocketClient* client = [self findClient:cId callback:callback];
if (!client) return; if (!client) return;
// iOS7+ // iOS7+
@ -95,13 +85,13 @@ RCT_EXPORT_METHOD(send:(nonnull NSNumber*)cId
RCT_EXPORT_METHOD(close:(nonnull NSNumber*)cId RCT_EXPORT_METHOD(close:(nonnull NSNumber*)cId
callback:(RCTResponseSenderBlock)callback) { callback:(RCTResponseSenderBlock)callback) {
[UdpSockets closeClient:cId callback:callback]; [self closeClient:cId callback:callback];
} }
RCT_EXPORT_METHOD(setBroadcast:(nonnull NSNumber*)cId RCT_EXPORT_METHOD(setBroadcast:(nonnull NSNumber*)cId
flag:(BOOL)flag flag:(BOOL)flag
callback:(RCTResponseSenderBlock)callback) { callback:(RCTResponseSenderBlock)callback) {
UdpSocketClient* client = [UdpSockets findClient:cId callback:callback]; UdpSocketClient* client = [self findClient:cId callback:callback];
if (!client) return; if (!client) return;
NSError *error = nil; NSError *error = nil;
@ -126,7 +116,6 @@ RCT_EXPORT_METHOD(dropMembership:(nonnull NSNumber*)cId
- (void) onData:(UdpSocketClient*) client data:(NSData *)data host:(NSString *)host port:(uint16_t)port - (void) onData:(UdpSocketClient*) client data:(NSData *)data host:(NSString *)host port:(uint16_t)port
{ {
NSMutableDictionary<NSNumber *, UdpSocketClient *> *_clients = [UdpSockets clients];
NSNumber *clientID = [[_clients allKeysForObject:client] objectAtIndex:0]; NSNumber *clientID = [[_clients allKeysForObject:client] objectAtIndex:0];
NSString *base64String = [data base64EncodedStringWithOptions:0]; NSString *base64String = [data base64EncodedStringWithOptions:0];
[self.bridge.eventDispatcher sendDeviceEventWithName:[NSString stringWithFormat:@"udp-%@-data", clientID] [self.bridge.eventDispatcher sendDeviceEventWithName:[NSString stringWithFormat:@"udp-%@-data", clientID]
@ -138,10 +127,9 @@ RCT_EXPORT_METHOD(dropMembership:(nonnull NSNumber*)cId
]; ];
} }
+(UdpSocketClient*)findClient:(nonnull NSNumber*)cId callback:(RCTResponseSenderBlock)callback -(UdpSocketClient*)findClient:(nonnull NSNumber*)cId callback:(RCTResponseSenderBlock)callback
{ {
NSMutableDictionary<NSNumber *, UdpSocketClient *> *_clients = [UdpSockets clients]; UdpSocketClient *client = _clients[cId];
UdpSocketClient *client = [_clients objectForKey:cId];
if (!client) { if (!client) {
if (!callback) { if (!callback) {
RCTLogError(@"%@.missing callback parameter.", [self class]); RCTLogError(@"%@.missing callback parameter.", [self class]);
@ -156,24 +144,17 @@ RCT_EXPORT_METHOD(dropMembership:(nonnull NSNumber*)cId
return client; return client;
} }
+(void) closeClient:(nonnull NSNumber*)cId -(void) closeClient:(nonnull NSNumber*)cId
callback:(RCTResponseSenderBlock)callback callback:(RCTResponseSenderBlock)callback
{ {
NSMutableDictionary<NSNumber *, UdpSocketClient *> *_clients = [UdpSockets clients]; UdpSocketClient* client = [self findClient:cId callback:callback];
UdpSocketClient* client = [UdpSockets findClient:cId callback:callback];
if (!client) return; if (!client) return;
client.clientDelegate = nil;
[client close]; [client close];
[_clients removeObjectForKey:cId]; [_clients removeObjectForKey:cId];
if (callback) callback(@[]); if (callback) callback(@[]);
} }
+(void) closeAllSockets {
NSMutableDictionary<NSNumber *, UdpSocketClient *> *_clients = [UdpSockets clients];
for (NSNumber* cId in _clients) {
[UdpSockets closeClient:cId callback:nil];
}
}
@end @end