diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..f942e1a --- /dev/null +++ b/.eslintignore @@ -0,0 +1 @@ +interfaces diff --git a/.flowconfig b/.flowconfig index 89dad58..b61e013 100644 --- a/.flowconfig +++ b/.flowconfig @@ -6,7 +6,7 @@ [include] [libs] -interfaces/react-native-interface.js +interfaces/ [options] module.system=haste @@ -25,4 +25,4 @@ suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(1[0-9]\\|[0-9]\\).[0-9 suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy [version] -^0.19.0 +0.20.1 diff --git a/TcpServer.js b/TcpServer.js new file mode 100644 index 0000000..feb61fe --- /dev/null +++ b/TcpServer.js @@ -0,0 +1,95 @@ +/** + * Copyright (c) 2015-present, Peel Technologies, Inc. + * All rights reserved. + * + * @providesModule TcpServer + * @flow + */ + +'use strict'; + +var inherits = require('inherits'); +var EventEmitter = require('events').EventEmitter; +var { + NativeModules +} = require('react-native'); +var Sockets = NativeModules.TcpSockets; + +var Socket = require('./TcpSocket'); + +function TcpServer(connectionListener: (socket: Socket) => void) { + if (!(this instanceof TcpServer)) { + return new TcpServer(connectionListener); + } + + // $FlowFixMe: suppressing this error flow doesn't like EventEmitter + EventEmitter.call(this); + + var self = this; + + this._socket = new Socket(); + // $FlowFixMe: suppressing this error flow doesn't like EventEmitter + this._socket.on('connect', function() { + self.emit('listening'); + }); + // $FlowFixMe: suppressing this error flow doesn't like EventEmitter + this._socket.on('error', function(error) { + self.emit('error', error); + self._socket.destroy(); + }); + // $FlowFixMe: suppressing this error flow doesn't like EventEmitter + this._socket.on('close', function() { + self.emit('close'); + }); + // $FlowFixMe: suppressing this error flow doesn't like EventEmitter + this._socket.on('connection', function(socketId) { + self._connections++; + + var socket = new Socket({ _id: socketId }); + self.emit('connection', socket); + }); + + if (connectionListener === typeof 'function') { + self.on('connection', connectionListener); + } + + this._connections = 0; +} + +inherits(TcpServer, EventEmitter); + +TcpServer.prototype._debug = function() { + if (__DEV__) { + var args = [].slice.call(arguments); + console.log.apply(console, args); + } +}; + +TcpServer.prototype.listen = function(options: { port: number, hostname: ?string }, callback: ?() => void) : TcpServer { + var port = Number(options.port); + var hostname = options.hostname || 'localhost'; + + if (callback) { + this.on('listening', callback); + } + + Sockets.listen(this._socket._id, hostname, port); + + return this; +}; + +TcpServer.prototype.getConnections = function(callback: (err: ?any, count: number) => void) { + if (typeof callback === 'function') { + callback.invoke(null, this._connections); + } +}; + +TcpServer.prototype.close = function(callback: ?() => void) { + if (callback) { + this.on('close', callback); + } + + this._socket.end(); +}; + +module.exports = TcpServer; diff --git a/TcpSocket.js b/TcpSocket.js index 9b6dd88..f39a6eb 100644 --- a/TcpSocket.js +++ b/TcpSocket.js @@ -1,11 +1,7 @@ -// -// react-native-tcp -// -// Created by Andy Prock on 12/14/15. -// Copyright (c) 2015 Peel, Inc. All rights reserved. -// - /** + * Copyright (c) 2015-present, Peel Technologies, Inc. + * All rights reserved. + * * @providesModule TcpSocket * @flow */ @@ -30,9 +26,8 @@ var STATE = { CONNECTED: 2 }; -exports.Socket = TcpSocket; - -function TcpSocket(options) { +function TcpSocket(options: ?any) { + // $FlowFixMe: suppressing this error flow doesn't like EventEmitter EventEmitter.call(this); options = options || {}; @@ -53,20 +48,8 @@ function TcpSocket(options) { usedIds.push(this._id); this._state = nativeSocket ? STATE.CONNECTED : STATE.DISCONNECTED; - this._connecting = false; - this._hadError = false; this._host = null; - if (typeof options === 'number') { - options = { fd: options }; - } else if (options === undefined) { - options = {}; - } - - if (options.fd) { - throw new Error('file descriptors are unsupoprted at this time.'); - } - // these will be set once there is a connection this.readable = this.writable = false; @@ -94,7 +77,7 @@ TcpSocket.prototype._debug = function() { } }; -TcpSocket.prototype.connect = function(options, callback) { +TcpSocket.prototype.connect = function(options: { port: number, host: ?string, localAddress: ?string, localPort: ?number, family: ?number }, callback: ?() => void) { if (this._state !== STATE.DISCONNECTED) { throw new Error('Socket is already bound'); } @@ -127,7 +110,6 @@ TcpSocket.prototype.connect = function(options, callback) { port |= port; this._state = STATE.CONNECTING; - this._connecting = true; this._debug('connecting, host:', host, 'port:', port); Sockets.connect(this._id, host, Number(port), options); @@ -135,14 +117,14 @@ TcpSocket.prototype.connect = function(options, callback) { // Check that the port number is not NaN when coerced to a number, // is an integer and that it falls within the legal range of port numbers. -function isLegalPort(port) { +function isLegalPort(port: number) : boolean { if (typeof port === 'string' && port.trim() === '') { return false; } return +port === (port >>> 0) && port >= 0 && port <= 0xFFFF; } -TcpSocket.prototype.setTimeout = function(msecs, callback) { +TcpSocket.prototype.setTimeout = function(msecs: number, callback: () => void) { var self = this; if (this._timeout) { @@ -156,11 +138,11 @@ TcpSocket.prototype.setTimeout = function(msecs, callback) { } var self = this; - this._timeout = setTimeout(msecs, function() { + this._timeout = setTimeout(function() { self.emit('timeout'); self._timeout = null; self.destroy(); - }); + }, msecs); } }; @@ -222,13 +204,12 @@ TcpSocket.prototype.destroy = function() { } }; -TcpSocket.prototype._onEvent = function(info) { +TcpSocket.prototype._onEvent = function(info: { event: string, data: ?any }) { this._debug('received', info.event); if (info.event === 'connect') { this.writable = this.readable = true; this._state = STATE.CONNECTED; - this._connecting = false; } else if (info.event === 'data') { if (this._timeout) { clearTimeout(this._timeout); @@ -291,7 +272,7 @@ TcpSocket.prototype.write = function(buffer, encoding, callback) { }); }; -function normalizeError (err) { +function normalizeError(err) { if (err) { if (typeof err === 'string') { err = new Error(err); @@ -301,74 +282,4 @@ function normalizeError (err) { } } -exports.Server = TcpServer; - -function TcpServer(options, connectionListener) { - if (!(this instanceof TcpServer)) { - return new TcpServer(options, connectionListener); - } - - EventEmitter.call(this); - - var self = this; - - this._socket = new exports.Socket(options); - this._socket.on('connect', function() { - self.emit('listening'); - }); - this._socket.on('error', function(error) { - self.emit('error', error); - self._socket.destroy(); - }); - this._socket.on('close', function() { - self.emit('close'); - }); - this._socket.on('connection', function(socketId) { - var socket = new exports.Socket({_id : socketId }); - self.emit('connection', socket); - }); - - if (typeof options === 'function') { - connectionListener = options; - options = {}; - self.on('connection', connectionListener); - } else { - options = options || {}; - - if (typeof connectionListener === 'function') { - self.on('connection', connectionListener); - } - } - - // this._connections = 0; - - // this.allowHalfOpen = options.allowHalfOpen || false; - // this.pauseOnConnect = !!options.pauseOnConnect; -} - -inherits(TcpServer, EventEmitter); - -TcpServer.prototype.listen = function(options, callback) { - var port = Number(options.port); - var hostname = options.hostname || 'localhost'; - - if (callback) { - this.on('listening', callback); - } - - Sockets.listen(this._socket._id, hostname, port); - - return this; -}; - -TcpServer.prototype.getConnections = function(callback) { - /* nop */ -}; - -TcpServer.prototype.close = function(callback) { - if (callback) { - this.on('close', callback); - } - - this._socket.end(); -}; +module.exports = TcpSocket; diff --git a/TcpSockets.js b/TcpSockets.js index 0b259fa..a12a34b 100644 --- a/TcpSockets.js +++ b/TcpSockets.js @@ -1,62 +1,23 @@ /** + * Copyright (c) 2015-present, Peel Technologies, Inc. + * All rights reserved. + * * @providesModule TcpSockets * @flow */ + 'use strict'; var ipRegex = require('ip-regex'); -var Socket = require('./TcpSocket').Socket; -var Server = require('./TcpSocket').Server; +var Socket = require('./TcpSocket'); +var Server = require('./TcpServer'); -exports.createServer = function(options, connectionListener) { - return new Server(options, connectionListener); +exports.createServer = function(connectionListener: (socket: Socket) => void) : Server { + return new Server(connectionListener); }; - -// Target API: -// -// var s = net.connect({port: 80, host: 'google.com'}, function() { -// ... -// }); -// -// There are various forms: -// -// connect(options, [cb]) -// connect(port, [host], [cb]) -// connect(path, [cb]); -// -// exports.connect = exports.createConnection = function() { -// var args = normalizeConnectArgs(arguments); -// Socket._debug('createConnection', args); -// var s = new Socket(args[0]); -// return Socket.prototype.connect.apply(s, args); -// }; -// -// // Returns an array [options] or [options, cb] -// // It is the same as the argument of Socket.prototype.connect(). -// function normalizeConnectArgs(args) { -// var options = {}; -// -// if (args[0] !== null && typeof args[0] === 'object') { -// // connect(options, [cb]) -// options = args[0]; -// }/* else if (isPipeName(args[0])) { -// // connect(path, [cb]); -// options.path = args[0]; -// }*/ else { -// // connect(port, [host], [cb]) -// options.port = args[0]; -// if (typeof args[1] === 'string') { -// options.host = args[1]; -// } -// } -// -// var cb = args[args.length - 1]; -// return typeof cb === 'function' ? [options, cb] : [options]; -// } - -exports.connect = exports.createConnection = function(options: { port: number, host: ?string, localAddress: ?string, localPort: ?number, family: ?number }, callback : ?any) : Socket { +exports.connect = exports.createConnection = function(options: { port: number, host: ?string, localAddress: ?string, localPort: ?number, family: ?number }, callback: ?() => void) : Socket { var tcpSocket = new Socket(); tcpSocket.connect(options, callback); return tcpSocket; diff --git a/android/build.gradle b/android/build.gradle index 447d675..fae7b74 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -27,5 +27,5 @@ android { dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:appcompat-v7:23.0.1' - compile 'com.facebook.react:react-native:0.11.+' + compile 'com.facebook.react:react-native:0.17.+' } diff --git a/android/src/main/java/com/peel/react/TcpSockets.java b/android/src/main/java/com/peel/react/TcpSockets.java index d6a1ff3..9b04dea 100644 --- a/android/src/main/java/com/peel/react/TcpSockets.java +++ b/android/src/main/java/com/peel/react/TcpSockets.java @@ -1,8 +1,6 @@ /** - * TcpSockets.java - * react-native-tcp - * - * Created by Andy Prock on 12/21/15. + * Copyright (c) 2015-present, Peel Technologies, Inc. + * All rights reserved. */ package com.peel.react; @@ -80,53 +78,72 @@ public final class TcpSockets extends ReactContextBaseJavaModule { @ReactMethod public void connect(final Integer cId, final @Nullable String host, final Integer port, final ReadableMap options) { - new GuardedAsyncTask(getReactApplicationContext()) { - @Override - protected void doInBackgroundGuarded(Void... params) { - FLog.e(TAG, "TcpSockets.connect unimplemented."); + new GuardedAsyncTask(getReactApplicationContext()) { + @Override + protected void doInBackgroundGuarded(Void... params) { + FLog.e(TAG, "TcpSockets.connect unimplemented."); - WritableMap eventParams = Arguments.createMap(); - eventParams.putString("event", "error"); - eventParams.putString("data", "TcpSockets.connect unimplemented"); + WritableMap eventParams = Arguments.createMap(); + eventParams.putString("event", "error"); + eventParams.putString("data", "TcpSockets.connect unimplemented"); - ReactContext reactContext = TcpSockets.this.getReactApplicationContext(); - reactContext - .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) - .emit("tcp-" + cId + "-event", eventParams); - } - }.execute(); + ReactContext reactContext = TcpSockets.this.getReactApplicationContext(); + reactContext + .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) + .emit("tcp-" + cId + "-event", eventParams); + } + }.execute(); } @ReactMethod public void write(final Integer cId, final String base64String, final boolean encoded, final Callback callback) { - new GuardedAsyncTask(getReactApplicationContext()) { - @Override - protected void doInBackgroundGuarded(Void... params) { - FLog.e(TAG, "TcpSockets.write unimplemented."); - callback.invoke("unimplemented." + cId); - } - }.execute(); + new GuardedAsyncTask(getReactApplicationContext()) { + @Override + protected void doInBackgroundGuarded(Void... params) { + FLog.e(TAG, "TcpSockets.write unimplemented."); + callback.invoke("unimplemented." + cId); + } + }.execute(); } @ReactMethod public void end(final Integer cId, final Callback callback) { - new GuardedAsyncTask(getReactApplicationContext()) { - @Override - protected void doInBackgroundGuarded(Void... params) { - FLog.e(TAG, "TcpSockets.end unimplemented."); - callback.invoke("unimplemented." + cId); - } - }.execute(); + new GuardedAsyncTask(getReactApplicationContext()) { + @Override + protected void doInBackgroundGuarded(Void... params) { + FLog.e(TAG, "TcpSockets.end unimplemented."); + callback.invoke("unimplemented." + cId); + } + }.execute(); } @ReactMethod public void destroy(final Integer cId, final Callback callback) { - new GuardedAsyncTask(getReactApplicationContext()) { - @Override - protected void doInBackgroundGuarded(Void... params) { - FLog.e(TAG, "TcpSockets.destroy unimplemented."); - callback.invoke("unimplemented." + cId); - } - }.execute(); + new GuardedAsyncTask(getReactApplicationContext()) { + @Override + protected void doInBackgroundGuarded(Void... params) { + FLog.e(TAG, "TcpSockets.destroy unimplemented."); + callback.invoke("unimplemented." + cId); + } + }.execute(); + } + + @ReactMethod + public void listen(final Integer cId, final String host, final Integer port) { + new GuardedAsyncTask(getReactApplicationContext()) { + @Override + protected void doInBackgroundGuarded(Void... params) { + FLog.e(TAG, "TcpSockets.listen unimplemented."); + + WritableMap eventParams = Arguments.createMap(); + eventParams.putString("event", "error"); + eventParams.putString("data", "TcpSockets.connect unimplemented"); + + ReactContext reactContext = TcpSockets.this.getReactApplicationContext(); + reactContext + .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) + .emit("tcp-" + cId + "-event", eventParams); + } + }.execute(); } } diff --git a/android/src/main/java/com/peel/react/TcpSocketsModule.java b/android/src/main/java/com/peel/react/TcpSocketsModule.java index 89b913f..3690bf9 100644 --- a/android/src/main/java/com/peel/react/TcpSocketsModule.java +++ b/android/src/main/java/com/peel/react/TcpSocketsModule.java @@ -1,8 +1,6 @@ /** - * TcpSocketsModule.java - * react-native-tcp - * - * Created by Andy Prock on 12/21/15. + * Copyright (c) 2015-present, Peel Technologies, Inc. + * All rights reserved. */ package com.peel.react; diff --git a/base64-str.js b/base64-str.js index ee1a3d7..410fd37 100644 --- a/base64-str.js +++ b/base64-str.js @@ -1,5 +1,8 @@ /** - * Source: https://gist.github.com/ncerminara/11257943 + * @providesModule base64-js + * @noflow + * + * Original Source: https://gist.github.com/ncerminara/11257943 */ 'use strict'; diff --git a/examples/rctsockets/index.js b/examples/rctsockets/index.js index 4f92b6c..c3cf0bb 100644 --- a/examples/rctsockets/index.js +++ b/examples/rctsockets/index.js @@ -1,3 +1,8 @@ +/** + * Copyright (c) 2015-present, Peel Technologies, Inc. + * All rights reserved. + */ + 'use strict'; var React = require('react-native'); @@ -21,13 +26,6 @@ var aPort = randomPort(); var a = net.createServer({}, function(socket) { console.log('server connected'); - // socket.on('data', function (data) { - // var str = String.fromCharCode.apply(null, new Uint8Array(data)); - // console.log('a received', str); - // a.close(); - // b.end(); - // }); - socket.on('data', function (data) { console.log('Server Received: ' + data); socket.write('Echo server\r\n'); @@ -38,14 +36,6 @@ var a = net.createServer({}, function(socket) { }); }).listen({ port: aPort }); -// a.on('listening', function() { -// console.log('listening'); -// }); -// -// a.on('error', function(error) { -// console.log('error ' + error); -// }); - var b = net.createConnection({ port: aPort }, function(err) { if (err) { throw err; diff --git a/interfaces/interface.js b/interfaces/interface.js new file mode 100644 index 0000000..a9738ef --- /dev/null +++ b/interfaces/interface.js @@ -0,0 +1,13 @@ +/** + * Copyright (c) 2015-present, Peel Technologies, Inc. + * All rights reserved. + * + * @flow + */ + +declare var __DEV__: boolean; + +declare module 'react-native' { + declare var NativeModules: any; + declare var DeviceEventEmitter: any; +} diff --git a/interfaces/react-native-interface.js b/interfaces/react-native-interface.js deleted file mode 100644 index 623ffd9..0000000 --- a/interfaces/react-native-interface.js +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @flow - */ - -// see also react-native.js - -declare var __DEV__: boolean; - -declare var __REACT_DEVTOOLS_GLOBAL_HOOK__: any; /*?{ - inject: ?((stuff: Object) => void) -};*/ - -declare var fetch: any; -declare var Headers: any; -declare var Request: any; -declare var Response: any; -declare module requestAnimationFrame { - declare var exports: (callback: any) => any; -} diff --git a/ios/TcpSocketClient.h b/ios/TcpSocketClient.h index 006de4b..580b035 100644 --- a/ios/TcpSocketClient.h +++ b/ios/TcpSocketClient.h @@ -1,10 +1,7 @@ -// -// TcpSocketClient.h -// react-native-tcp -// -// Created by Andy Prock on 12/14/15. -// Copyright (c) 2015 Peel, Inc. All rights reserved. -// +/** + * Copyright (c) 2015-present, Peel Technologies, Inc. + * All rights reserved. + */ #import #import "RCTBridgeModule.h" diff --git a/ios/TcpSocketClient.m b/ios/TcpSocketClient.m index a44e3c1..2ffac75 100644 --- a/ios/TcpSocketClient.m +++ b/ios/TcpSocketClient.m @@ -1,10 +1,7 @@ -// -// TcpSocketClient.m -// react-native-tcp -// -// Created by Andy Prock on 12/14/15. -// Copyright (c) 2015 peel, Inc. All rights reserved. -// +/** + * Copyright (c) 2015-present, Peel Technologies, Inc. + * All rights reserved. + */ #import #import diff --git a/ios/TcpSockets.h b/ios/TcpSockets.h index 9ac89c5..1d975b0 100644 --- a/ios/TcpSockets.h +++ b/ios/TcpSockets.h @@ -1,10 +1,7 @@ -// -// TcpSockets.h -// react-native-tcp -// -// Created by Andy Prock on 12/14/15. -// Copyright (c) 2015 Peel, Inc. All rights reserved. -// +/** + * Copyright (c) 2015-present, Peel Technologies, Inc. + * All rights reserved. + */ #import #import diff --git a/ios/TcpSockets.m b/ios/TcpSockets.m index 2dd9a48..2501e97 100644 --- a/ios/TcpSockets.m +++ b/ios/TcpSockets.m @@ -1,10 +1,7 @@ -// -// TcpSockets.m -// react-native-tcp -// -// Created by Andy Prock on 12/14/15. -// Copyright (c) 2015 Peel, Inc. All rights reserved. -// +/** + * Copyright (c) 2015-present, Peel Technologies, Inc. + * All rights reserved. + */ #import "RCTAssert.h" #import "RCTBridge.h" diff --git a/ios/react-native-tcp.podspec b/ios/react-native-tcp.podspec index 466180f..b5668c8 100644 --- a/ios/react-native-tcp.podspec +++ b/ios/react-native-tcp.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'react-native-tcp' - s.version = '1.1.1' + s.version = '0.0.3' s.summary = 'node\'s net API in React Native.' s.description = <<-DESC Enables accessing tcp sockets in React Native. @@ -9,16 +9,10 @@ Pod::Spec.new do |s| s.license = { :type => 'MIT' } s.authors = { 'Andy Prock' => 'aprock@gmail.com' } s.source = { :git => 'https://github.com/PeelTechnologies/react-native-tcp.git' } - s.default_subspec = 'Core' s.requires_arc = true s.platform = :ios, '7.0' s.prepare_command = 'npm install --production' + s.source_files = '*.{c,h,m}', 'CocoaAsyncSocket/*.{h,m}' s.preserve_paths = 'node_modules', '**/*.js', 'package.json' s.header_mappings_dir = '.' - # s.dependency 'React' - - s.subspec 'Core' do |ss| - ss.source_files = '*.{c,h,m}', 'CocoaAsyncSocket/*.{h,m}' - ss.preserve_paths = '*.js' - end end diff --git a/package.json b/package.json index 6bc07f8..126b642 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "react-native-tcp", "version": "0.0.2", - "description": "node's dgram API for react-native", + "description": "node's net API for react-native", "main": "TcpSockets.js", "scripts": { "start": "exit 1" @@ -27,7 +27,8 @@ "name": "Andy Prock", "email": "aprock@gmail.com" }, - "license": "MIT", + "license": "UNLICENSED", + "private": true, "bugs": { "url": "https://github.com/PeelTechnologies/react-native-tcp/issues" },