From 516530edbd2af0e1b15237cf9ad0e488f35f919e Mon Sep 17 00:00:00 2001 From: Mark Vayngrib Date: Sat, 16 May 2015 11:45:11 -0400 Subject: [PATCH] fix data transfer over RCTBridge, for now use base64 strings until they support binary data transfer --- UdpSocket.ios.js | 44 ++++++++++++++------------------------------ UdpSockets.m | 16 +++++++--------- index.ios.js | 21 +++------------------ package.json | 8 ++++++-- 4 files changed, 30 insertions(+), 59 deletions(-) diff --git a/UdpSocket.ios.js b/UdpSocket.ios.js index 1ed9dc0..a5aa651 100644 --- a/UdpSocket.ios.js +++ b/UdpSocket.ios.js @@ -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 \ No newline at end of file diff --git a/UdpSockets.m b/UdpSockets.m index 2abcc08..bdc924d 100644 --- a/UdpSockets.m +++ b/UdpSockets.m @@ -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] } diff --git a/index.ios.js b/index.ios.js index e92f475..2143d4f 100644 --- a/index.ios.js +++ b/index.ios.js @@ -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); diff --git a/package.json b/package.json index c7f8402..0ad9ee8 100644 --- a/package.json +++ b/package.json @@ -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 ", + "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" } }