switch to NativeEventEmitter for sending events
This commit is contained in:
parent
6d623aaa4c
commit
6fa42c9438
52
TcpSocket.js
52
TcpSocket.js
|
@ -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 = [];
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.');
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue