switch to NativeEventEmitter for sending events

This commit is contained in:
Andy Prock 2017-01-13 12:42:52 -08:00
parent 6d623aaa4c
commit 6fa42c9438
7 changed files with 125 additions and 73 deletions

View File

@ -16,7 +16,7 @@ var stream = require('stream-browserify');
// var EventEmitter = require('events').EventEmitter;
var ipRegex = require('ip-regex');
var {
DeviceEventEmitter,
NativeEventEmitter,
NativeModules
} = require('react-native');
var Sockets = NativeModules.TcpSockets;
@ -47,6 +47,7 @@ function TcpSocket(options: ?{ id: ?number }) {
this._id = instances++;
}
this._eventEmitter = new NativeEventEmitter(Sockets);
stream.Duplex.call(this, {});
// ensure compatibility with node's EventEmitter
@ -248,28 +249,41 @@ TcpSocket.prototype._registerEvents = function(): void {
}
this._subs = [
DeviceEventEmitter.addListener(
'tcp-' + this._id + '-connect', this._onConnect.bind(this)
),
DeviceEventEmitter.addListener(
'tcp-' + this._id + '-connection', this._onConnection.bind(this)
),
DeviceEventEmitter.addListener(
'tcp-' + this._id + '-data', this._onData.bind(this)
),
DeviceEventEmitter.addListener(
'tcp-' + this._id + '-close', this._onClose.bind(this)
),
DeviceEventEmitter.addListener(
'tcp-' + this._id + '-error', this._onError.bind(this)
)
this._eventEmitter.addListener('connect', ev => {
if (this._id !== ev.id) {
return;
}
this._onConnect(ev.address);
}),
this._eventEmitter.addListener('connection', ev => {
if (this._id !== ev.id) {
return;
}
this._onConnection(ev.info);
}),
this._eventEmitter.addListener('data', ev => {
if (this._id !== ev.id) {
return;
}
this._onData(ev.data);
}),
this._eventEmitter.addListener('close', ev => {
if (this._id !== ev.id) {
return;
}
this._onClose(ev.hadError);
}),
this._eventEmitter.addListener('error', ev => {
if (this._id !== ev.id) {
return;
}
this._onError(ev.error);
})
];
};
TcpSocket.prototype._unregisterEvents = function(): void {
this._subs.forEach(function(listener) {
listener.remove();
});
this._subs.forEach(e => e.remove());
this._subs = [];
};

View File

@ -35,8 +35,11 @@ public final class TcpSockets extends ReactContextBaseJavaModule implements TcpS
private boolean mShuttingDown = false;
private TcpSocketManager socketManager;
private ReactContext mReactContext;
public TcpSockets(ReactApplicationContext reactContext) {
super(reactContext);
mReactContext = reactContext;
try {
socketManager = new TcpSocketManager(this);
@ -73,6 +76,12 @@ public final class TcpSockets extends ReactContextBaseJavaModule implements TcpS
}
}
private void sendEvent(String eventName, WritableMap params) {
mReactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(eventName, params);
}
@ReactMethod
public void listen(final Integer cId, final String host, final Integer port) {
new GuardedAsyncTask<Void, Void>(getReactApplicationContext()) {
@ -146,19 +155,20 @@ public final class TcpSockets extends ReactContextBaseJavaModule implements TcpS
return;
}
WritableMap eventParams = Arguments.createMap();
eventParams.putInt("id", clientId);
eventParams.putInt("id", serverId);
WritableMap infoParams = Arguments.createMap();
infoParams.putInt("id", clientId);
WritableMap addressParams = Arguments.createMap();
addressParams.putString("address", socketAddress.getHostName());
addressParams.putInt("port", socketAddress.getPort());
addressParams.putString("family", socketAddress.getAddress() instanceof Inet6Address ? "IPv6" : "IPv4");
eventParams.putMap("address", addressParams);
infoParams.putMap("address", addressParams);
eventParams.putMap("info", infoParams);
ReactContext reactContext = TcpSockets.this.getReactApplicationContext();
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit("tcp-" + serverId + "-connection", eventParams);
sendEvent("connection", eventParams);
}
@Override
@ -167,14 +177,16 @@ public final class TcpSockets extends ReactContextBaseJavaModule implements TcpS
return;
}
WritableMap eventParams = Arguments.createMap();
eventParams.putString("address", address.getHostName());
eventParams.putInt("port", address.getPort());
eventParams.putString("family", address.getAddress() instanceof Inet6Address ? "IPv6" : "IPv4");
eventParams.putInt("id", id);
ReactContext reactContext = TcpSockets.this.getReactApplicationContext();
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit("tcp-" + id + "-connect", eventParams);
WritableMap addressParams = Arguments.createMap();
addressParams.putString("address", address.getHostName());
addressParams.putInt("port", address.getPort());
addressParams.putString("family", address.getAddress() instanceof Inet6Address ? "IPv6" : "IPv4");
eventParams.putMap("address", addressParams);
sendEvent("connect", eventParams);
}
@Override
@ -182,10 +194,11 @@ public final class TcpSockets extends ReactContextBaseJavaModule implements TcpS
if (mShuttingDown) {
return;
}
ReactContext reactContext = TcpSockets.this.getReactApplicationContext();
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit("tcp-" + id + "-data", Base64.encodeToString(data, Base64.NO_WRAP));
WritableMap eventParams = Arguments.createMap();
eventParams.putInt("id", id);
eventParams.putString("data", Base64.encodeToString(data, Base64.NO_WRAP));
sendEvent("data", eventParams);
}
@Override
@ -197,10 +210,11 @@ public final class TcpSockets extends ReactContextBaseJavaModule implements TcpS
onError(id, error);
}
ReactContext reactContext = TcpSockets.this.getReactApplicationContext();
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit("tcp-" + id + "-close", error != null);
WritableMap eventParams = Arguments.createMap();
eventParams.putInt("id", id);
eventParams.putBoolean("hadError", error != null);
sendEvent("close", eventParams);
}
@Override
@ -208,9 +222,11 @@ public final class TcpSockets extends ReactContextBaseJavaModule implements TcpS
if (mShuttingDown) {
return;
}
ReactContext reactContext = TcpSockets.this.getReactApplicationContext();
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit("tcp-" + id + "-error", error);
WritableMap eventParams = Arguments.createMap();
eventParams.putInt("id", id);
eventParams.putString("error", error);
sendEvent("error", eventParams);
}
}

View File

@ -48,6 +48,10 @@ class RctSockets extends Component {
socket.on('error', (error) => {
this.updateChatter('error ' + error);
});
socket.on('close', (error) => {
this.updateChatter('server client closed ' + (error ? error : ''));
});
}).listen(serverPort, () => {
this.updateChatter('opened server on ' + JSON.stringify(server.address()));
});
@ -56,6 +60,10 @@ class RctSockets extends Component {
this.updateChatter('error ' + error);
});
server.on('close', () => {
this.updateChatter('server close');
});
let client = net.createConnection(serverPort, () => {
this.updateChatter('opened client on ' + JSON.stringify(client.address()));
client.write('Hello, server! Love, Client.');

View File

@ -4,6 +4,7 @@
*/
#import <Foundation/Foundation.h>
#import "CocoaAsyncSocket/GCDAsyncSocket.h"
#import "RCTBridgeModule.h"
extern NSString *const RCTTCPErrorDomain;
@ -35,7 +36,7 @@ typedef enum RCTTCPError RCTTCPError;
@end
@interface TcpSocketClient : NSObject
@interface TcpSocketClient : NSObject<GCDAsyncSocketDelegate>
@property (nonatomic, retain) NSNumber * id;
@property (nonatomic, weak) id<SocketClientDelegate> clientDelegate;

View File

@ -8,7 +8,6 @@
#import "TcpSocketClient.h"
#import "RCTBridgeModule.h"
#import "RCTLog.h"
#import "GCDAsyncSocket.h"
NSString *const RCTTCPErrorDomain = @"RCTTCPErrorDomain";
@ -203,7 +202,7 @@ NSString *const RCTTCPErrorDomain = @"RCTTCPErrorDomain";
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {
if (!_clientDelegate) {
RCTLogError(@"didReadData with nil clientDelegate for %@", [sock userData]);
RCTLogWarn(@"didReadData with nil clientDelegate for %@", [sock userData]);
return;
}
@ -225,7 +224,7 @@ NSString *const RCTTCPErrorDomain = @"RCTTCPErrorDomain";
- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port
{
if (!_clientDelegate) {
RCTLogError(@"didConnectToHost with nil clientDelegate for %@", [sock userData]);
RCTLogWarn(@"didConnectToHost with nil clientDelegate for %@", [sock userData]);
return;
}
@ -244,7 +243,7 @@ NSString *const RCTTCPErrorDomain = @"RCTTCPErrorDomain";
- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err
{
if (!_clientDelegate) {
RCTLogError(@"socketDidDisconnect with nil clientDelegate for %@", [sock userData]);
RCTLogWarn(@"socketDidDisconnect with nil clientDelegate for %@", [sock userData]);
return;
}

View File

@ -5,12 +5,11 @@
#import <Foundation/Foundation.h>
#import <Availability.h>
#import "GCDAsyncSocket.h"
#import "TcpSocketClient.h"
#import "CocoaAsyncSocket/GCDAsyncSocket.h"
#import "RCTBridgeModule.h"
#import "RCTBridge.h"
#import "RCTEventDispatcher.h"
#import "TcpSocketClient.h"
#import "RCTEventEmitter.h"
@interface TcpSockets : NSObject<SocketClientDelegate, RCTBridgeModule>
@interface TcpSockets : RCTEventEmitter<SocketClientDelegate>
@end

View File

@ -4,9 +4,8 @@
*/
#import "RCTAssert.h"
#import "RCTBridge.h"
#import "RCTConvert.h"
#import "RCTEventDispatcher.h"
#import "RCTConvert.h"
#import "RCTLog.h"
#import "TcpSockets.h"
#import "TcpSocketClient.h"
@ -22,7 +21,22 @@
RCT_EXPORT_MODULE()
@synthesize bridge = _bridge;
- (NSArray<NSString *> *)supportedEvents
{
return @[@"connect",
@"connection",
@"data",
@"close",
@"error"];
}
- (void)startObserving {
// Does nothing
}
- (void)stopObserving {
// Does nothing
}
-(void)dealloc
{
@ -34,7 +48,7 @@ RCT_EXPORT_MODULE()
- (TcpSocketClient *)createSocket:(nonnull NSNumber*)cId
{
if (!cId) {
RCTLogError(@"%@.createSocket called with nil id parameter.", [self class]);
RCTLogWarn(@"%@.createSocket called with nil id parameter.", [self class]);
return nil;
}
@ -43,7 +57,7 @@ RCT_EXPORT_MODULE()
}
if (_clients[cId]) {
RCTLogError(@"%@.createSocket called twice with the same id.", [self class]);
RCTLogWarn(@"%@.createSocket called twice with the same id.", [self class]);
return nil;
}
@ -109,45 +123,45 @@ RCT_EXPORT_METHOD(listen:(nonnull NSNumber*)cId
- (void)onConnect:(TcpSocketClient*) client
{
[self.bridge.eventDispatcher sendDeviceEventWithName:[NSString stringWithFormat:@"tcp-%@-connect", client.id]
body:[client getAddress]];
[self sendEventWithName:@"connect"
body:@{ @"id": client.id, @"address" : [client getAddress] }];
}
-(void)onConnection:(TcpSocketClient *)client toClient:(NSNumber *)clientID {
_clients[client.id] = client;
[self.bridge.eventDispatcher sendDeviceEventWithName:[NSString stringWithFormat:@"tcp-%@-connection", clientID]
body:@{ @"id": client.id, @"address" : [client getAddress] }];
[self sendEventWithName:@"connection"
body:@{ @"id": clientID, @"info": @{ @"id": client.id, @"address" : [client getAddress] } }];
}
- (void)onData:(NSNumber *)clientID data:(NSData *)data
{
NSString *base64String = [data base64EncodedStringWithOptions:0];
[self.bridge.eventDispatcher sendDeviceEventWithName:[NSString stringWithFormat:@"tcp-%@-data", clientID]
body:base64String];
[self sendEventWithName:@"data"
body:@{ @"id": clientID, @"data" : base64String }];
}
- (void)onClose:(NSNumber*) clientID withError:(NSError *)err
{
TcpSocketClient* client = [self findClient:clientID];
if (!client) {
RCTLogError(@"onClose: unrecognized client id %@", clientID);
RCTLogWarn(@"onClose: unrecognized client id %@", clientID);
}
if (err) {
[self onError:client withError:err];
}
[self.bridge.eventDispatcher sendDeviceEventWithName:[NSString stringWithFormat:@"tcp-%@-close", client.id]
body:err == nil ? @NO : @YES];
[self sendEventWithName:@"close"
body:@{ @"id": clientID, @"hadError": err == nil ? @NO : @YES }];
[_clients removeObjectForKey:client.id];
[_clients removeObjectForKey:clientID];
}
- (void)onError:(TcpSocketClient*) client withError:(NSError *)err {
NSString *msg = err.localizedFailureReason ?: err.localizedDescription;
[self.bridge.eventDispatcher sendDeviceEventWithName:[NSString stringWithFormat:@"tcp-%@-error", client.id]
body:msg];
[self sendEventWithName:@"error"
body:@{ @"id": client.id, @"error": msg }];
}
@ -156,8 +170,9 @@ RCT_EXPORT_METHOD(listen:(nonnull NSNumber*)cId
TcpSocketClient *client = _clients[cId];
if (!client) {
NSString *msg = [NSString stringWithFormat:@"no client found with id %@", cId];
[self.bridge.eventDispatcher sendDeviceEventWithName:[NSString stringWithFormat:@"tcp-%@-error", cId]
body:msg];
[self sendEventWithName:@"error"
body:@{ @"id": cId, @"error": msg }];
return nil;
}