fix data transfer over RCTBridge, for now use base64 strings until they support binary data transfer

This commit is contained in:
Mark Vayngrib 2015-05-16 11:45:11 -04:00
parent 686dc283a8
commit 516530edbd
4 changed files with 30 additions and 59 deletions

View File

@ -16,6 +16,7 @@ var React = require('react-native')
var mixInEventEmitter = require('mixInEventEmitter')
var DeviceEventEmitter = require('RCTDeviceEventEmitter')
var Sockets = require('NativeModules').UdpSockets
var base64 = require('base64-js')
var noop = function () {}
var instances = 0
var STATE = {
@ -96,7 +97,7 @@ UdpSocket.prototype.close = function() {
UdpSocket.prototype._onReceive = function(info) {
this._debug('received', info)
var buf = toByteArray(info.data)
var buf = base64.toByteArray(info.data)
var rinfo = {
address: info.address,
port: info.port,
@ -145,15 +146,23 @@ UdpSocket.prototype.send = function(buffer, offset, length, port, address, callb
}
callback = callback || noop
var str
if (typeof buffer === 'string') {
buffer = toByteArray(buffer)
console.warn('socket.send(): interpreting as base64')
str = buffer
}
else if (typeof Buffer !== 'undefined' && Buffer.isBuffer(buffer)) {
buffer = buffer.toJSON().data
str = buffer.toString('base64')
}
else if (buffer instanceof Uint8Array || Array.isArray(buffer)) {
str = base64.fromByteArray(buffer)
}
else {
throw new Error('invalid message format')
}
self._debug('sending', buffer)
Sockets.send(this._id, buffer, +port, address, function(err) {
self._debug('sending', buffer, str)
Sockets.send(this._id, str, +port, address, function(err) {
if (err) {
self._debug('send failed', err)
return callback(err)
@ -215,29 +224,4 @@ mixInEventEmitter(UdpSocket, {
'error': true
})
function toByteArray(obj) {
if (typeof obj === 'object') {
var i = 0
var arr = []
while (true) {
if (!(i in obj)) break
arr.push(+obj[i])
i++
}
return new Uint8Array(arr)
}
else if (typeof obj !== 'string') {
throw new Error('unsupported format')
}
var uint = new Uint8Array(obj.length);
for (var i = 0, l = obj.length; i < l; i++){
uint[i] = obj.charCodeAt(i);
}
return new Uint8Array(uint);
}
module.exports = UdpSocket

View File

@ -58,13 +58,16 @@ RCT_EXPORT_METHOD(bind:(NSString*)cId
}
RCT_EXPORT_METHOD(send:(NSString*)cId
data:(NSData*)data
base64String:(NSString*)base64String
port:(int)port
address:(NSString*)address
callback:(RCTResponseSenderBlock)callback) {
UdpSocketClient* client = [self findClient:cId callback:callback];
if (!client) return;
// iOS7+
// TODO: use https://github.com/nicklockwood/Base64 for compatibility with earlier iOS versions
NSData *data = [[NSData alloc] initWithBase64EncodedString:base64String options:0];
[client send:data remotePort:port remoteAddress:address callback:callback];
if (callback) callback(@[]);
}
@ -83,15 +86,10 @@ RCT_EXPORT_METHOD(close:(NSString*)cId
- (void) onData:(UdpSocketClient*) client data:(NSData *)data host:(NSString *)host port:(uint16_t)port
{
NSString *clientID = [[_clients allKeysForObject:client] objectAtIndex:0];
NSPropertyListFormat format;
NSArray* arr = [NSPropertyListSerialization propertyListFromData:data
mutabilityOption:NSPropertyListMutableContainers
format:&format
errorDescription:NULL];
NSString *base64String = [data base64EncodedStringWithOptions:0];
[self.bridge.eventDispatcher sendDeviceEventWithName:[NSString stringWithFormat:@"udp-%@-data", clientID]
body:@{
@"data": arr,
@"data": base64String,
@"address": host,
@"port": [NSNumber numberWithInt:port]
}

View File

@ -16,7 +16,8 @@ function randomPort() {
return Math.random() * 65536 | 0
}
var dgram = require('RCTUDP')
var base64 = require('base64-js')
var dgram = require('dgram')
var a = dgram.createSocket('udp4')
var aPort = randomPort()
a.bind(bPort, function(err) {
@ -92,24 +93,8 @@ var styles = StyleSheet.create({
},
});
// only works for 8-bit chars
function toByteArray(obj) {
if (typeof obj === 'object') {
var i = 0
var arr = []
while (true) {
if (!(i in obj)) break
arr.push(+obj[i])
i++
}
return new Uint8Array(arr)
}
else if (typeof obj !== 'string') {
throw new Error('unsupported format')
}
var uint = new Uint8Array(obj.length);
for (var i = 0, l = obj.length; i < l; i++){
uint[i] = obj.charCodeAt(i);

View File

@ -11,7 +11,7 @@
},
"repository": {
"type": "git",
"url": "https://github.com/tradle/react-native-udp.git"
"url": "https://github.com/tradle/react-native-udp"
},
"keywords": [
"react-component",
@ -22,13 +22,17 @@
"sockets",
"ios"
],
"author": "Mark Vayngrib <mark.vayngrib@lablz.com>",
"author": {
"name": "Mark Vayngrib",
"email": "mark.vayngrib@lablz.com"
},
"license": "MIT",
"bugs": {
"url": "https://github.com/tradle/react-native-udp/issues"
},
"homepage": "https://github.com/tradle/react-native-udp",
"dependencies": {
"base64-js": "0.0.8",
"react-native": "^0.4.2"
}
}