├── .eslintignore
├── .eslintrc
├── .flowconfig
├── .gitignore
├── .npmignore
├── LICENSE
├── README.md
├── TcpServer.js
├── TcpSocket.js
├── TcpSockets.js
├── TcpSockets.podspec
├── android
├── .classpath
├── .project
├── .settings
│ └── org.eclipse.buildship.core.prefs
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── src
│ └── main
│ ├── AndroidManifest.xml
│ └── java
│ └── com
│ └── peel
│ └── react
│ ├── TcpSocketListener.java
│ ├── TcpSocketManager.java
│ ├── TcpSockets.java
│ └── TcpSocketsModule.java
├── base64-str.js
├── examples
└── rctsockets
│ ├── .babelrc
│ ├── .buckconfig
│ ├── .flowconfig
│ ├── .gitattributes
│ ├── .gitignore
│ ├── .watchmanconfig
│ ├── __tests__
│ ├── index.android.js
│ └── index.ios.js
│ ├── android
│ ├── app
│ │ ├── BUCK
│ │ ├── build.gradle
│ │ ├── proguard-rules.pro
│ │ └── src
│ │ │ └── main
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── java
│ │ │ └── com
│ │ │ │ └── rctsockets
│ │ │ │ ├── MainActivity.java
│ │ │ │ └── MainApplication.java
│ │ │ └── res
│ │ │ ├── mipmap-hdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-mdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ └── ic_launcher.png
│ │ │ └── values
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ ├── build.gradle
│ ├── gradle.properties
│ ├── gradle
│ │ └── wrapper
│ │ │ ├── gradle-wrapper.jar
│ │ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ ├── keystores
│ │ ├── BUCK
│ │ └── debug.keystore.properties
│ └── settings.gradle
│ ├── index.android.js
│ ├── index.ios.js
│ ├── ios
│ ├── rctsockets.xcodeproj
│ │ ├── project.pbxproj
│ │ └── xcshareddata
│ │ │ └── xcschemes
│ │ │ └── rctsockets.xcscheme
│ ├── rctsockets
│ │ ├── AppDelegate.h
│ │ ├── AppDelegate.m
│ │ ├── Base.lproj
│ │ │ └── LaunchScreen.xib
│ │ ├── Images.xcassets
│ │ │ └── AppIcon.appiconset
│ │ │ │ └── Contents.json
│ │ ├── Info.plist
│ │ └── main.m
│ └── rctsocketsTests
│ │ ├── Info.plist
│ │ └── rctsocketsTests.m
│ ├── package.json
│ └── shim.js
├── interfaces
└── interface.js
├── ios
├── TcpSocketClient.h
├── TcpSocketClient.m
├── TcpSockets.h
├── TcpSockets.m
└── TcpSockets.xcodeproj
│ └── project.pbxproj
├── package-lock.json
└── package.json
/.eslintignore:
--------------------------------------------------------------------------------
1 | interfaces
2 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "parser": "babel-eslint",
3 |
4 | "ecmaFeatures": {
5 | "jsx": true
6 | },
7 |
8 | "env": {
9 | "es6": true,
10 | "jasmine": true,
11 | },
12 |
13 | "plugins": [
14 | "react"
15 | ],
16 |
17 | // Map from global var to bool specifying if it can be redefined
18 | "globals": {
19 | "__DEV__": true,
20 | "__dirname": false,
21 | "__fbBatchedBridgeConfig": false,
22 | "cancelAnimationFrame": false,
23 | "clearImmediate": true,
24 | "clearInterval": false,
25 | "clearTimeout": false,
26 | "console": false,
27 | "document": false,
28 | "escape": false,
29 | "exports": false,
30 | "fetch": false,
31 | "global": false,
32 | "jest": false,
33 | "Map": true,
34 | "module": false,
35 | "navigator": false,
36 | "process": false,
37 | "Promise": true,
38 | "requestAnimationFrame": true,
39 | "require": false,
40 | "Set": true,
41 | "setImmediate": true,
42 | "setInterval": false,
43 | "setTimeout": false,
44 | "window": false,
45 | "XMLHttpRequest": false,
46 | "pit": false
47 | },
48 |
49 | "rules": {
50 | "comma-dangle": 0, // disallow trailing commas in object literals
51 | "no-cond-assign": 1, // disallow assignment in conditional expressions
52 | "no-console": 0, // disallow use of console (off by default in the node environment)
53 | "no-constant-condition": 0, // disallow use of constant expressions in conditions
54 | "no-control-regex": 1, // disallow control characters in regular expressions
55 | "no-debugger": 1, // disallow use of debugger
56 | "no-dupe-keys": 1, // disallow duplicate keys when creating object literals
57 | "no-empty": 0, // disallow empty statements
58 | "no-ex-assign": 1, // disallow assigning to the exception in a catch block
59 | "no-extra-boolean-cast": 1, // disallow double-negation boolean casts in a boolean context
60 | "no-extra-parens": 0, // disallow unnecessary parentheses (off by default)
61 | "no-extra-semi": 1, // disallow unnecessary semicolons
62 | "no-func-assign": 1, // disallow overwriting functions written as function declarations
63 | "no-inner-declarations": 0, // disallow function or variable declarations in nested blocks
64 | "no-invalid-regexp": 1, // disallow invalid regular expression strings in the RegExp constructor
65 | "no-negated-in-lhs": 1, // disallow negation of the left operand of an in expression
66 | "no-obj-calls": 1, // disallow the use of object properties of the global object (Math and JSON) as functions
67 | "no-regex-spaces": 1, // disallow multiple spaces in a regular expression literal
68 | "no-reserved-keys": 0, // disallow reserved words being used as object literal keys (off by default)
69 | "no-sparse-arrays": 1, // disallow sparse arrays
70 | "no-unreachable": 1, // disallow unreachable statements after a return, throw, continue, or break statement
71 | "use-isnan": 1, // disallow comparisons with the value NaN
72 | "valid-jsdoc": 0, // Ensure JSDoc comments are valid (off by default)
73 | "valid-typeof": 1, // Ensure that the results of typeof are compared against a valid string
74 |
75 | // Best Practices
76 | // These are rules designed to prevent you from making mistakes. They either prescribe a better way of doing something or help you avoid footguns.
77 |
78 | "block-scoped-var": 0, // treat var statements as if they were block scoped (off by default)
79 | "complexity": 0, // specify the maximum cyclomatic complexity allowed in a program (off by default)
80 | "consistent-return": 0, // require return statements to either always or never specify values
81 | "curly": 1, // specify curly brace conventions for all control statements
82 | "default-case": 0, // require default case in switch statements (off by default)
83 | "dot-notation": 1, // encourages use of dot notation whenever possible
84 | "eqeqeq": 1, // require the use of === and !==
85 | "guard-for-in": 0, // make sure for-in loops have an if statement (off by default)
86 | "no-alert": 1, // disallow the use of alert, confirm, and prompt
87 | "no-caller": 1, // disallow use of arguments.caller or arguments.callee
88 | "no-div-regex": 1, // disallow division operators explicitly at beginning of regular expression (off by default)
89 | "no-else-return": 0, // disallow else after a return in an if (off by default)
90 | "no-empty-label": 1, // disallow use of labels for anything other then loops and switches
91 | "no-eq-null": 0, // disallow comparisons to null without a type-checking operator (off by default)
92 | "no-eval": 1, // disallow use of eval()
93 | "no-extend-native": 1, // disallow adding to native types
94 | "no-extra-bind": 1, // disallow unnecessary function binding
95 | "no-fallthrough": 1, // disallow fallthrough of case statements
96 | "no-floating-decimal": 1, // disallow the use of leading or trailing decimal points in numeric literals (off by default)
97 | "no-implied-eval": 1, // disallow use of eval()-like methods
98 | "no-labels": 1, // disallow use of labeled statements
99 | "no-iterator": 1, // disallow usage of __iterator__ property
100 | "no-lone-blocks": 1, // disallow unnecessary nested blocks
101 | "no-loop-func": 0, // disallow creation of functions within loops
102 | "no-multi-str": 0, // disallow use of multiline strings
103 | "no-native-reassign": 0, // disallow reassignments of native objects
104 | "no-new": 1, // disallow use of new operator when not part of the assignment or comparison
105 | "no-new-func": 1, // disallow use of new operator for Function object
106 | "no-new-wrappers": 1, // disallows creating new instances of String,Number, and Boolean
107 | "no-octal": 1, // disallow use of octal literals
108 | "no-octal-escape": 1, // disallow use of octal escape sequences in string literals, such as var foo = "Copyright \251";
109 | "no-proto": 1, // disallow usage of __proto__ property
110 | "no-redeclare": 0, // disallow declaring the same variable more then once
111 | "no-return-assign": 1, // disallow use of assignment in return statement
112 | "no-script-url": 1, // disallow use of javascript: urls.
113 | "no-self-compare": 1, // disallow comparisons where both sides are exactly the same (off by default)
114 | "no-sequences": 1, // disallow use of comma operator
115 | "no-unused-expressions": 0, // disallow usage of expressions in statement position
116 | "no-void": 1, // disallow use of void operator (off by default)
117 | "no-warning-comments": 0, // disallow usage of configurable warning terms in comments": 1, // e.g. TODO or FIXME (off by default)
118 | "no-with": 1, // disallow use of the with statement
119 | "radix": 1, // require use of the second argument for parseInt() (off by default)
120 | "semi-spacing": 1, // require a space after a semi-colon
121 | "vars-on-top": 0, // requires to declare all vars on top of their containing scope (off by default)
122 | "wrap-iife": 0, // require immediate function invocation to be wrapped in parentheses (off by default)
123 | "yoda": 1, // require or disallow Yoda conditions
124 |
125 | // Strict Mode
126 | // These rules relate to using strict mode.
127 |
128 | "strict": [2, "global"], // require or disallow the "use strict" pragma in the global scope (off by default in the node environment)
129 |
130 | // Variables
131 | // These rules have to do with variable declarations.
132 |
133 | "no-catch-shadow": 1, // disallow the catch clause parameter name being the same as a variable in the outer scope (off by default in the node environment)
134 | "no-delete-var": 1, // disallow deletion of variables
135 | "no-label-var": 1, // disallow labels that share a name with a variable
136 | "no-shadow": 1, // disallow declaration of variables already declared in the outer scope
137 | "no-shadow-restricted-names": 1, // disallow shadowing of names such as arguments
138 | "no-undef": 2, // disallow use of undeclared variables unless mentioned in a /*global */ block
139 | "no-undefined": 0, // disallow use of undefined variable (off by default)
140 | "no-undef-init": 1, // disallow use of undefined when initializing variables
141 | "no-unused-vars": [1, {"vars": "all", "args": "none"}], // disallow declaration of variables that are not used in the code
142 | "no-use-before-define": 0, // disallow use of variables before they are defined
143 |
144 | // Node.js
145 | // These rules are specific to JavaScript running on Node.js.
146 |
147 | "handle-callback-err": 1, // enforces error handling in callbacks (off by default) (on by default in the node environment)
148 | "no-mixed-requires": 1, // disallow mixing regular variable and require declarations (off by default) (on by default in the node environment)
149 | "no-new-require": 1, // disallow use of new operator with the require function (off by default) (on by default in the node environment)
150 | "no-path-concat": 1, // disallow string concatenation with __dirname and __filename (off by default) (on by default in the node environment)
151 | "no-process-exit": 0, // disallow process.exit() (on by default in the node environment)
152 | "no-restricted-modules": 1, // restrict usage of specified node modules (off by default)
153 | "no-sync": 0, // disallow use of synchronous methods (off by default)
154 |
155 | // Stylistic Issues
156 | // These rules are purely matters of style and are quite subjective.
157 |
158 | "key-spacing": 0,
159 | "comma-spacing": 0,
160 | "no-multi-spaces": 0,
161 | "brace-style": 0, // enforce one true brace style (off by default)
162 | "camelcase": 0, // require camel case names
163 | "consistent-this": [1, "self"], // enforces consistent naming when capturing the current execution context (off by default)
164 | "eol-last": 1, // enforce newline at the end of file, with no multiple empty lines
165 | "func-names": 0, // require function expressions to have a name (off by default)
166 | "func-style": 0, // enforces use of function declarations or expressions (off by default)
167 | "new-cap": 0, // require a capital letter for constructors
168 | "new-parens": 1, // disallow the omission of parentheses when invoking a constructor with no arguments
169 | "no-nested-ternary": 0, // disallow nested ternary expressions (off by default)
170 | "no-array-constructor": 1, // disallow use of the Array constructor
171 | "no-lonely-if": 0, // disallow if as the only statement in an else block (off by default)
172 | "no-new-object": 1, // disallow use of the Object constructor
173 | "no-spaced-func": 1, // disallow space between function identifier and application
174 | "no-ternary": 0, // disallow the use of ternary operators (off by default)
175 | "no-trailing-spaces": 1, // disallow trailing whitespace at the end of lines
176 | "no-underscore-dangle": 0, // disallow dangling underscores in identifiers
177 | "no-mixed-spaces-and-tabs": 1, // disallow mixed spaces and tabs for indentation
178 | "quotes": [1, "single", "avoid-escape"], // specify whether double or single quotes should be used
179 | "quote-props": 0, // require quotes around object literal property names (off by default)
180 | "semi": 1, // require or disallow use of semicolons instead of ASI
181 | "sort-vars": 0, // sort variables within the same declaration block (off by default)
182 | "space-after-keywords": 1, // require a space after certain keywords (off by default)
183 | "space-in-brackets": 0, // require or disallow spaces inside brackets (off by default)
184 | "space-in-parens": 0, // require or disallow spaces inside parentheses (off by default)
185 | "space-infix-ops": 1, // require spaces around operators
186 | "space-return-throw-case": 1, // require a space after return, throw, and case
187 | "space-unary-ops": [1, { "words": true, "nonwords": false }], // require or disallow spaces before/after unary operators (words on by default, nonwords off by default)
188 | "max-nested-callbacks": 0, // specify the maximum depth callbacks can be nested (off by default)
189 | "one-var": 0, // allow just one var statement per function (off by default)
190 | "wrap-regex": 0, // require regex literals to be wrapped in parentheses (off by default)
191 |
192 | // Legacy
193 | // The following rules are included for compatibility with JSHint and JSLint. While the names of the rules may not match up with the JSHint/JSLint counterpart, the functionality is the same.
194 |
195 | "max-depth": 0, // specify the maximum depth that blocks can be nested (off by default)
196 | "max-len": 0, // specify the maximum length of a line in your program (off by default)
197 | "max-params": 0, // limits the number of parameters that can be used in the function declaration. (off by default)
198 | "max-statements": 0, // specify the maximum number of statement allowed in a function (off by default)
199 | "no-bitwise": 0, // disallow use of bitwise operators (off by default)
200 | "no-plusplus": 0, // disallow use of unary operators, ++ and -- (off by default)
201 |
202 | "react/display-name": 0,
203 | "react/jsx-boolean-value": 0,
204 | "jsx-quotes": [2, "prefer-single"],
205 | "react/jsx-no-undef": 1,
206 | "react/jsx-sort-props": 0,
207 | "react/jsx-uses-react": 0,
208 | "react/jsx-uses-vars": 1,
209 | "react/no-did-mount-set-state": [1, "allow-in-func"],
210 | "react/no-did-update-set-state": [1, "allow-in-func"],
211 | "react/no-multi-comp": 0,
212 | "react/no-unknown-property": 0,
213 | "react/prop-types": 0,
214 | "react/react-in-jsx-scope": 0,
215 | "react/self-closing-comp": 1,
216 | "react/wrap-multilines": 0
217 | }
218 | }
219 |
--------------------------------------------------------------------------------
/.flowconfig:
--------------------------------------------------------------------------------
1 | [ignore]
2 |
3 | # We fork some components by platform.
4 | .*/*.web.js
5 | .*/*.android.js
6 |
7 | # Some modules have their own node_modules with overlap
8 | .*/node_modules/node-haste/.*
9 |
10 | # Ugh
11 | .*/node_modules/babel.*
12 | .*/node_modules/babylon.*
13 | .*/node_modules/invariant.*
14 |
15 | # Ignore react and fbjs where there are overlaps, but don't ignore
16 | # anything that react-native relies on
17 | .*/node_modules/fbjs/lib/Map.js
18 | .*/node_modules/fbjs/lib/ErrorUtils.js
19 |
20 | # Flow has a built-in definition for the 'react' module which we prefer to use
21 | # over the currently-untyped source
22 | .*/node_modules/react/react.js
23 | .*/node_modules/react/lib/React.js
24 | .*/node_modules/react/lib/ReactDOM.js
25 |
26 | .*/__mocks__/.*
27 | .*/__tests__/.*
28 |
29 | .*/commoner/test/source/widget/share.js
30 |
31 | # Ignore commoner tests
32 | .*/node_modules/commoner/test/.*
33 |
34 | # See https://github.com/facebook/flow/issues/442
35 | .*/react-tools/node_modules/commoner/lib/reader.js
36 |
37 | # Ignore jest
38 | .*/node_modules/jest-cli/.*
39 |
40 | # Ignore Website
41 | .*/website/.*
42 |
43 | # Ignore generators
44 | .*/local-cli/generator.*
45 |
46 | # Ignore BUCK generated folders
47 | .*\.buckd/
48 |
49 | # Ignore RNPM
50 | .*/local-cli/rnpm/.*
51 |
52 | .*/node_modules/is-my-json-valid/test/.*\.json
53 | .*/node_modules/iconv-lite/encodings/tables/.*\.json
54 | .*/node_modules/y18n/test/.*\.json
55 | .*/node_modules/spdx-license-ids/spdx-license-ids.json
56 | .*/node_modules/spdx-exceptions/index.json
57 | .*/node_modules/resolve/test/subdirs/node_modules/a/b/c/x.json
58 | .*/node_modules/resolve/lib/core.json
59 | .*/node_modules/jsonparse/samplejson/.*\.json
60 | .*/node_modules/json5/test/.*\.json
61 | .*/node_modules/ua-parser-js/test/.*\.json
62 | .*/node_modules/builtin-modules/builtin-modules.json
63 | .*/node_modules/binary-extensions/binary-extensions.json
64 | .*/node_modules/url-regex/tlds.json
65 | .*/node_modules/joi/.*\.json
66 | .*/node_modules/isemail/.*\.json
67 | .*/node_modules/tr46/.*\.json
68 |
69 |
70 | [include]
71 |
72 | [libs]
73 | node_modules/react-native/Libraries/react-native/react-native-interface.js
74 | node_modules/react-native/flow
75 | flow/
76 |
77 | [options]
78 | module.system=haste
79 |
80 | esproposal.class_static_fields=enable
81 | esproposal.class_instance_fields=enable
82 |
83 | munge_underscores=true
84 |
85 | module.name_mapper='^image![a-zA-Z0-9$_-]+$' -> 'GlobalImageStub'
86 | module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub'
87 |
88 | suppress_type=$FlowIssue
89 | suppress_type=$FlowFixMe
90 | suppress_type=$FixMe
91 |
92 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(2[0-5]\\|1[0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
93 | suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(2[0-5]\\|1[0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+
94 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
95 |
96 | [version]
97 | ^0.25.0
98 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # OSX
2 | #
3 | .DS_Store
4 |
5 | # Xcode
6 | #
7 | build/
8 | *.pbxuser
9 | !default.pbxuser
10 | *.mode1v3
11 | !default.mode1v3
12 | *.mode2v3
13 | !default.mode2v3
14 | *.perspectivev3
15 | !default.perspectivev3
16 | xcuserdata
17 | *.xccheckout
18 | *.moved-aside
19 | DerivedData
20 | *.hmap
21 | *.ipa
22 | *.xcuserstate
23 | project.xcworkspace
24 |
25 | # Android/IJ
26 | #
27 | *.iml
28 | .idea
29 | .gradle
30 | local.properties
31 |
32 | # node.js
33 | #
34 | node_modules/
35 | npm-debug.log
36 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | examples
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Peel Technologies, Inc
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # TCP in React Native
2 |
3 | node's [net](https://nodejs.org/api/net.html) API in React Native
4 |
5 | This module is used by [Peel](http://www.peel.com/)
6 |
7 | ## Install
8 |
9 | * Create a new react-native project. [Check react-native getting started](http://facebook.github.io/react-native/docs/getting-started.html#content)
10 |
11 | * In your project dir:
12 |
13 | ```
14 | npm install react-native-tcp --save
15 | ```
16 |
17 | __Note for iOS:__ If your react-native version < 0.40 install with this tag instead:
18 | ```
19 | npm install react-native-tcp@3.1.0 --save
20 | ```
21 | ## if using Cocoapods
22 |
23 | Update the following line with your path to `node_modules/` and add it to your
24 | podfile:
25 |
26 | ```ruby
27 | pod 'TcpSockets', :path => '../node_modules/react-native-tcp'
28 | ```
29 |
30 | ## Link in the native dependency
31 |
32 | ```
33 | react-native link react-native-tcp
34 | ```
35 |
36 | ## Additional dependencies
37 |
38 | ### Due to limitations in the react-native packager, streams need to be hacked in with [rn-nodeify](https://www.npmjs.com/package/rn-nodeify)
39 |
40 | 1. install rn-nodeify as a dev-dependency
41 | ``` npm install --save-dev rn-nodeify ```
42 | 2. run rn-nodeify manually
43 | ``` rn-nodeify --install stream,process,util --hack ```
44 | 3. optionally you can add this as a postinstall script
45 | ``` "postinstall": "rn-nodeify --install stream,process,util --hack" ```
46 |
47 | ## Usage
48 |
49 | ### package.json
50 |
51 | _only if you want to write require('net') in your javascript_
52 |
53 | ```json
54 | {
55 | "browser": {
56 | "net": "react-native-tcp"
57 | }
58 | }
59 | ```
60 |
61 | ### JS
62 |
63 | _see/run [index.ios.js/index.android.js](examples/rctsockets) for a complete example, but basically it's just like net_
64 |
65 | ```js
66 | var net = require('net');
67 | // OR, if not shimming via package.json "browser" field:
68 | // var net = require('react-native-tcp')
69 |
70 | var server = net.createServer(function(socket) {
71 | socket.write('excellent!');
72 | }).listen(12345);
73 |
74 | var client = net.createConnection(12345);
75 |
76 | client.on('error', function(error) {
77 | console.log(error)
78 | });
79 |
80 | client.on('data', function(data) {
81 | console.log('message was received', data)
82 | });
83 | ```
84 |
85 | ### TODO
86 |
87 | add select tests from node's tests for net
88 |
89 | PR's welcome!
90 |
91 |
92 |
93 | _originally forked from [react-native-udp](https://github.com/tradle/react-native-udp)_
94 |
--------------------------------------------------------------------------------
/TcpServer.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2015-present, Peel Technologies, Inc.
3 | * All rights reserved.
4 | *
5 | * @providesModule TcpServer
6 | * @flow
7 | */
8 |
9 | var util = require('util');
10 | var EventEmitter = require('events').EventEmitter;
11 | var { NativeModules } = require('react-native');
12 | var Sockets = NativeModules.TcpSockets;
13 |
14 | var Socket = require('./TcpSocket');
15 |
16 | function TcpServer(connectionListener: (socket: Socket) => void) {
17 | if (!(this instanceof TcpServer)) {
18 | return new TcpServer(connectionListener);
19 | }
20 |
21 | if (EventEmitter instanceof Function) {
22 | EventEmitter.call(this);
23 | }
24 |
25 | var self = this;
26 |
27 | this._socket = new Socket();
28 |
29 | // $FlowFixMe: suppressing this error flow doesn't like EventEmitter
30 | this._socket.on('connect', function () {
31 | self.emit('listening');
32 | });
33 | // $FlowFixMe: suppressing this error flow doesn't like EventEmitter
34 | this._socket.on('connection', function (socket) {
35 | self._connections++;
36 | self.emit('connection', socket);
37 | });
38 | // $FlowFixMe: suppressing this error flow doesn't like EventEmitter
39 | this._socket.on('error', function (error) {
40 | self.emit('error', error);
41 | });
42 |
43 | if (typeof connectionListener === 'function') {
44 | self.on('connection', connectionListener);
45 | }
46 |
47 | this._connections = 0;
48 | }
49 |
50 | util.inherits(TcpServer, EventEmitter);
51 |
52 | TcpServer.prototype._debug = function () {
53 | if (__DEV__) {
54 | var args = [].slice.call(arguments);
55 | console.log.apply(console, args);
56 | }
57 | };
58 |
59 | // TODO : determine how to properly overload this with flow
60 | TcpServer.prototype.listen = function (): TcpServer {
61 | var args = this._socket._normalizeConnectArgs(arguments);
62 | var options = args[0];
63 | var callback = args[1];
64 |
65 | var port = options.port;
66 | var host = options.host || '0.0.0.0';
67 |
68 | if (callback) {
69 | this.once('listening', callback);
70 | }
71 |
72 | this._socket._registerEvents();
73 | Sockets.listen(this._socket._id, host, port);
74 |
75 | return this;
76 | };
77 |
78 | TcpServer.prototype.getConnections = function (
79 | callback: (err: ?any, count: number) => void,
80 | ) {
81 | if (typeof callback === 'function') {
82 | callback.invoke(null, this._connections);
83 | }
84 | };
85 |
86 | TcpServer.prototype.address = function (): {
87 | port: number,
88 | address: string,
89 | family: string,
90 | } {
91 | return this._socket ? this._socket.address() : {};
92 | };
93 |
94 | TcpServer.prototype.close = function (callback: ?() => void) {
95 | if (typeof callback === 'function') {
96 | if (!this._socket) {
97 | this.once('close', function close() {
98 | callback(new Error('Not running'));
99 | });
100 | } else {
101 | this.once('close', callback);
102 | }
103 | }
104 |
105 | if (this._socket) {
106 | this._socket.end();
107 | }
108 |
109 | var self = this;
110 | setImmediate(function () {
111 | self.emit('close');
112 | });
113 | };
114 |
115 | // unimplemented net.Server apis
116 | TcpServer.prototype.ref = TcpServer.prototype.unref = function () {
117 | /* nop */
118 | };
119 |
120 | module.exports = TcpServer;
121 |
--------------------------------------------------------------------------------
/TcpSocket.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2015-present, Peel Technologies, Inc.
3 | * All rights reserved.
4 | *
5 | * @providesModule TcpSocket
6 | * @flow
7 | */
8 |
9 | if (!(global.process && global.process.nextTick)) {
10 | global.process = require('process'); // needed to make stream-browserify happy
11 | }
12 |
13 | var Buffer = (global.Buffer = global.Buffer || require('buffer').Buffer);
14 |
15 | var util = require('util');
16 | var stream = require('stream-browserify');
17 | // var EventEmitter = require('events').EventEmitter;
18 | var ipRegex = require('ip-regex');
19 | var { NativeEventEmitter, NativeModules } = require('react-native');
20 | var Sockets = NativeModules.TcpSockets;
21 | var base64 = require('base64-js');
22 | var Base64Str = require('./base64-str');
23 | var noop = function () { };
24 | var instances = 0;
25 | var STATE = {
26 | DISCONNECTED: 0,
27 | CONNECTING: 1,
28 | CONNECTED: 2,
29 | };
30 |
31 | function TcpSocket(options: ?{ id: ?number }) {
32 | if (!(this instanceof TcpSocket)) {
33 | return new TcpSocket(options);
34 | }
35 |
36 | if (options && options.id) {
37 | // e.g. incoming server connections
38 | this._id = Number(options.id);
39 |
40 | if (this._id <= instances) {
41 | throw new Error('Socket id ' + this._id + 'already in use');
42 | }
43 | } else {
44 | // javascript generated sockets range from 1-1000
45 | this._id = instances++;
46 | }
47 |
48 | this._eventEmitter = new NativeEventEmitter(Sockets);
49 | stream.Duplex.call(this, {});
50 |
51 | // ensure compatibility with node's EventEmitter
52 | if (!this.on) {
53 | this.on = this.addListener.bind(this);
54 | }
55 |
56 | // these will be set once there is a connection
57 | this.writable = this.readable = false;
58 |
59 | this._state = STATE.DISCONNECTED;
60 |
61 | this.read(0);
62 | }
63 |
64 | util.inherits(TcpSocket, stream.Duplex);
65 |
66 | TcpSocket.prototype._debug = function () {
67 | if (__DEV__) {
68 | var args = [].slice.call(arguments);
69 | args.unshift('socket-' + this._id);
70 | console.log.apply(console, args);
71 | }
72 | };
73 |
74 | // TODO : determine how to properly overload this with flow
75 | TcpSocket.prototype.connect = function (options, callback): TcpSocket {
76 | this._registerEvents();
77 |
78 | if (options === null || typeof options !== 'object') {
79 | // Old API:
80 | // connect(port, [host], [cb])
81 | var args = this._normalizeConnectArgs(arguments);
82 | return TcpSocket.prototype.connect.apply(this, args);
83 | }
84 |
85 | if (typeof callback === 'function') {
86 | this.once('connect', callback);
87 | }
88 |
89 | var host = options.host || 'localhost';
90 | var port = options.port || 0;
91 | var localAddress = options.localAddress;
92 | var localPort = options.localPort;
93 |
94 | if (localAddress && !ipRegex({ exact: true }).test(localAddress)) {
95 | throw new TypeError(
96 | '"localAddress" option must be a valid IP: ' + localAddress,
97 | );
98 | }
99 |
100 | if (localPort && typeof localPort !== 'number') {
101 | throw new TypeError('"localPort" option should be a number: ' + localPort);
102 | }
103 |
104 | if (typeof port !== 'undefined') {
105 | if (typeof port !== 'number' && typeof port !== 'string') {
106 | throw new TypeError(
107 | '"port" option should be a number or string: ' + port,
108 | );
109 | }
110 |
111 | port = +port;
112 |
113 | if (!isLegalPort(port)) {
114 | throw new RangeError('"port" option should be >= 0 and < 65536: ' + port);
115 | }
116 | }
117 |
118 | if (options.timeout) {
119 | this.setTimeout(options.timeout);
120 | } else if (this._timeout) {
121 | this._activeTimer(this._timeout.msecs);
122 | }
123 |
124 | this._state = STATE.CONNECTING;
125 | this._debug('connecting, host:', host, 'port:', port);
126 |
127 | this._destroyed = false;
128 | Sockets.connect(this._id, host, Number(port), options);
129 |
130 | return this;
131 | };
132 |
133 | // Check that the port number is not NaN when coerced to a number,
134 | // is an integer and that it falls within the legal range of port numbers.
135 | function isLegalPort(port: number): boolean {
136 | if (typeof port === 'string' && port.trim() === '') {
137 | return false;
138 | }
139 | return +port === port >>> 0 && port >= 0 && port <= 0xffff;
140 | }
141 |
142 | TcpSocket.prototype.read = function (n) {
143 | if (n === 0) {
144 | return stream.Readable.prototype.read.call(this, n);
145 | }
146 |
147 | this.read = stream.Readable.prototype.read;
148 | this._consuming = true;
149 | return this.read(n);
150 | };
151 |
152 | // Just call handle.readStart until we have enough in the buffer
153 | TcpSocket.prototype._read = function (n) {
154 | this._debug('_read');
155 |
156 | if (this._state === STATE.CONNECTING) {
157 | this._debug('_read wait for connection');
158 | this.once('connect', () => this._read(n));
159 | } else if (!this._reading) {
160 | // not already reading, start the flow
161 | this._debug('Socket._read resume');
162 | this._reading = true;
163 | this.resume();
164 | }
165 | };
166 |
167 | TcpSocket.prototype._activeTimer = function (msecs, wrapper) {
168 | if (this._timeout && this._timeout.handle) {
169 | clearTimeout(this._timeout.handle);
170 | }
171 |
172 | if (!wrapper) {
173 | var self = this;
174 | wrapper = function () {
175 | self._timeout = null;
176 | self.emit('timeout');
177 | };
178 | }
179 |
180 | this._timeout = {
181 | handle: setTimeout(wrapper, msecs),
182 | wrapper: wrapper,
183 | msecs: msecs,
184 | };
185 | };
186 |
187 | TcpSocket.prototype._clearTimeout = function () {
188 | if (this._timeout) {
189 | clearTimeout(this._timeout.handle);
190 | this._timeout = null;
191 | }
192 | };
193 |
194 | TcpSocket.prototype.setTimeout = function (msecs: number, callback: () => void) {
195 | if (msecs === 0) {
196 | this._clearTimeout();
197 | if (callback) {
198 | this.removeListener('timeout', callback);
199 | }
200 | } else {
201 | if (callback) {
202 | this.once('timeout', callback);
203 | }
204 |
205 | this._activeTimer(msecs);
206 | }
207 |
208 | return this;
209 | };
210 |
211 | TcpSocket.prototype.address = function (): {
212 | port: number,
213 | address: string,
214 | family: string,
215 | } {
216 | return this._address;
217 | };
218 |
219 | TcpSocket.prototype.end = function (data, encoding) {
220 | stream.Duplex.prototype.end.call(this, data, encoding);
221 | this.writable = false;
222 |
223 | if (this._destroyed) {
224 | return;
225 | }
226 |
227 | if (data) {
228 | this.write(data, encoding);
229 | }
230 |
231 | if (this.readable) {
232 | this.read(0);
233 | this.readable = false;
234 | }
235 |
236 | this._destroyed = true;
237 | this._debug('ending');
238 |
239 | Sockets.end(this._id);
240 | };
241 |
242 | TcpSocket.prototype.destroy = function () {
243 | if (!this._destroyed) {
244 | this._destroyed = true;
245 | this._debug('destroying');
246 | this._clearTimeout();
247 |
248 | Sockets.destroy(this._id);
249 | }
250 | };
251 |
252 | TcpSocket.prototype._registerEvents = function (): void {
253 | if (this._subs && this._subs.length > 0) {
254 | return;
255 | }
256 |
257 | this._subs = [
258 | this._eventEmitter.addListener('connect', ev => {
259 | if (this._id !== ev.id) {
260 | return;
261 | }
262 | this._onConnect(ev.address);
263 | }),
264 | this._eventEmitter.addListener('connection', ev => {
265 | if (this._id !== ev.id) {
266 | return;
267 | }
268 | this._onConnection(ev.info);
269 | }),
270 | this._eventEmitter.addListener('data', ev => {
271 | if (this._id !== ev.id) {
272 | return;
273 | }
274 | this._onData(ev.data);
275 | }),
276 | this._eventEmitter.addListener('close', ev => {
277 | if (this._id !== ev.id) {
278 | return;
279 | }
280 | this._onClose(ev.hadError);
281 | }),
282 | this._eventEmitter.addListener('error', ev => {
283 | if (this._id !== ev.id) {
284 | return;
285 | }
286 | this._onError(ev.error);
287 | }),
288 | ];
289 | };
290 |
291 | TcpSocket.prototype._unregisterEvents = function (): void {
292 | this._subs.forEach(e => e.remove());
293 | this._subs = [];
294 | };
295 |
296 | TcpSocket.prototype._onConnect = function (address: {
297 | port: number,
298 | address: string,
299 | family: string,
300 | }): void {
301 | this._debug('received', 'connect');
302 |
303 | setConnected(this, address);
304 | this.emit('connect');
305 |
306 | this.read(0);
307 | };
308 |
309 | TcpSocket.prototype._onConnection = function (info: {
310 | id: number,
311 | address: { port: number, address: string, family: string },
312 | }): void {
313 | this._debug('received', 'connection');
314 |
315 | var socket = new TcpSocket({ id: info.id });
316 |
317 | socket._registerEvents();
318 | setConnected(socket, info.address);
319 | this.emit('connection', socket);
320 | };
321 |
322 | TcpSocket.prototype._onData = function (data: string): void {
323 | this._debug('received', 'data');
324 |
325 | if (this._timeout) {
326 | this._activeTimer(this._timeout.msecs);
327 | }
328 |
329 | if (data && data.length > 0) {
330 | // debug('got data');
331 |
332 | // read success.
333 | // In theory (and in practice) calling readStop right now
334 | // will prevent this from being called again until _read() gets
335 | // called again.
336 |
337 | var ret = this.push(new Buffer(data, 'base64'));
338 | if (this._reading && !ret) {
339 | this._reading = false;
340 | this.pause();
341 | }
342 |
343 | return;
344 | }
345 | };
346 |
347 | TcpSocket.prototype._onClose = function (hadError: boolean): void {
348 | this._debug('received', 'close');
349 |
350 | setDisconnected(this, hadError);
351 | };
352 |
353 | TcpSocket.prototype._onError = function (error: string): void {
354 | this._debug('received', 'error');
355 |
356 | this.emit('error', normalizeError(error));
357 | this.destroy();
358 | };
359 |
360 | TcpSocket.prototype.write = function (chunk, encoding, cb) {
361 | if (typeof chunk !== 'string' && !Buffer.isBuffer(chunk)) {
362 | throw new TypeError(
363 | 'Invalid data, chunk must be a string or buffer, not ' + typeof chunk,
364 | );
365 | }
366 |
367 | return stream.Duplex.prototype.write.apply(this, arguments);
368 | };
369 |
370 | TcpSocket.prototype._write = function (
371 | buffer: any,
372 | encoding: ?String,
373 | callback: ?(err: ?Error) => void,
374 | ): boolean {
375 | var self = this;
376 |
377 | if (this._state === STATE.DISCONNECTED) {
378 | throw new Error('Socket is not connected.');
379 | } else if (this._state === STATE.CONNECTING) {
380 | // we're ok, GCDAsyncSocket handles queueing internally
381 | }
382 |
383 | callback = callback || noop;
384 | var str;
385 | if (typeof buffer === 'string') {
386 | self._debug('socket.WRITE(): encoding as base64');
387 | str = Base64Str.encode(buffer);
388 | } else if (Buffer.isBuffer(buffer)) {
389 | str = buffer.toString('base64');
390 | } else {
391 | throw new TypeError(
392 | 'Invalid data, chunk must be a string or buffer, not ' + typeof buffer,
393 | );
394 | }
395 |
396 | Sockets.write(this._id, str, function (err) {
397 | if (self._timeout) {
398 | self._activeTimer(self._timeout.msecs);
399 | }
400 |
401 | err = normalizeError(err);
402 | if (err) {
403 | self._debug('write failed', err);
404 | return callback(err);
405 | }
406 |
407 | callback();
408 | });
409 |
410 | return true;
411 | };
412 |
413 | function setConnected(
414 | socket: TcpSocket,
415 | address: { port: number, address: string, family: string },
416 | ) {
417 | socket.writable = socket.readable = true;
418 | socket._state = STATE.CONNECTED;
419 | socket._address = address;
420 | }
421 |
422 | function setDisconnected(socket: TcpSocket, hadError: boolean): void {
423 | if (socket._state === STATE.DISCONNECTED) {
424 | return;
425 | }
426 |
427 | socket._unregisterEvents();
428 | socket._state = STATE.DISCONNECTED;
429 | socket.emit('close', hadError);
430 | }
431 |
432 | function normalizeError(err) {
433 | if (err) {
434 | if (typeof err === 'string') {
435 | err = new Error(err);
436 | }
437 |
438 | return err;
439 | }
440 | }
441 |
442 | // Returns an array [options] or [options, cb]
443 | // It is the same as the argument of Socket.prototype.connect().
444 | TcpSocket.prototype._normalizeConnectArgs = function (args) {
445 | var options = {};
446 |
447 | if (args[0] !== null && typeof args[0] === 'object') {
448 | // connect(options, [cb])
449 | options = args[0];
450 | } else {
451 | // connect(port, [host], [cb])
452 | options.port = args[0];
453 | if (typeof args[1] === 'string') {
454 | options.host = args[1];
455 | }
456 | }
457 |
458 | var cb = args[args.length - 1];
459 | return typeof cb === 'function' ? [options, cb] : [options];
460 | };
461 |
462 | // unimplemented net.Socket apis
463 | TcpSocket.prototype.ref = TcpSocket.prototype.unref = TcpSocket.prototype.setNoDelay = TcpSocket.prototype.setKeepAlive = TcpSocket.prototype.setEncoding = function () {
464 | /* nop */
465 | };
466 |
467 | module.exports = TcpSocket;
468 |
--------------------------------------------------------------------------------
/TcpSockets.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2015-present, Peel Technologies, Inc.
3 | * All rights reserved.
4 | *
5 | * @providesModule TcpSockets
6 | * @flow
7 | */
8 |
9 | var ipRegex = require('ip-regex');
10 |
11 | var Socket = require('./TcpSocket');
12 | var Server = require('./TcpServer');
13 |
14 | exports.createServer = function (
15 | connectionListener: (socket: Socket) => void,
16 | ): Server {
17 | return new Server(connectionListener);
18 | };
19 |
20 | // TODO : determine how to properly overload this with flow
21 | exports.connect = exports.createConnection = function (): Socket {
22 | var tcpSocket = new Socket();
23 | return Socket.prototype.connect.apply(
24 | tcpSocket,
25 | tcpSocket._normalizeConnectArgs(arguments),
26 | );
27 | };
28 |
29 | exports.isIP = function (input: string): number {
30 | var result = 0;
31 | if (ipRegex.v4({ exact: true }).test(input)) {
32 | result = 4;
33 | } else if (ipRegex.v6({ exact: true }).test(input)) {
34 | result = 6;
35 | }
36 | return result;
37 | };
38 |
39 | exports.isIPv4 = function (input: string): boolean {
40 | return exports.isIP(input) === 4;
41 | };
42 |
43 | exports.isIPv6 = function (input: string): boolean {
44 | return exports.isIP(input) === 6;
45 | };
46 |
47 | exports.Socket = Socket;
48 | exports.Server = Server;
49 |
--------------------------------------------------------------------------------
/TcpSockets.podspec:
--------------------------------------------------------------------------------
1 | require 'json'
2 |
3 | package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
4 |
5 | Pod::Spec.new do |s|
6 |
7 | s.name = 'TcpSockets'
8 | s.version = package['version']
9 | s.summary = package['description']
10 | s.homepage = package['repository']['url']
11 | s.license = package['license']
12 | s.author = package['author']
13 | s.source = { :git => s.homepage, :tag => 'v#{s.version}' }
14 |
15 | s.requires_arc = true
16 | s.ios.deployment_target = '8.0'
17 | s.tvos.deployment_target = '9.0'
18 |
19 | s.preserve_paths = 'README.md', 'package.json', '**/*.js'
20 | s.source_files = 'ios/**/*.{h,m}'
21 | s.dependency 'React'
22 |
23 | end
24 |
--------------------------------------------------------------------------------
/android/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/android/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | react-native-tcp
4 | Project react-native-tcp created by Buildship.
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 | org.eclipse.buildship.core.gradleprojectbuilder
15 |
16 |
17 |
18 |
19 |
20 | org.eclipse.jdt.core.javanature
21 | org.eclipse.buildship.core.gradleprojectnature
22 |
23 |
24 |
--------------------------------------------------------------------------------
/android/.settings/org.eclipse.buildship.core.prefs:
--------------------------------------------------------------------------------
1 | connection.project.dir=../../../android
2 | eclipse.preferences.version=1
3 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | def safeExtGet(prop, fallback) {
2 | rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
3 | }
4 |
5 | buildscript {
6 | repositories {
7 | google()
8 | jcenter()
9 | }
10 |
11 | dependencies {
12 | classpath("com.android.tools.build:gradle:3.5.1")
13 | }
14 | }
15 |
16 | apply plugin: 'com.android.library'
17 |
18 | android {
19 |
20 | compileSdkVersion safeExtGet('compileSdkVersion', 29)
21 | buildToolsVersion safeExtGet('buildToolsVersion', '29.0.2')
22 |
23 | defaultConfig {
24 | minSdkVersion safeExtGet('minSdkVersion', 21)
25 | targetSdkVersion safeExtGet('targetSdkVersion', 29)
26 | versionCode 1
27 | versionName "0.2.0"
28 | }
29 |
30 |
31 | buildTypes {
32 | release {
33 | minifyEnabled false
34 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
35 | }
36 | }
37 |
38 | // needed for https://github.com/square/okio/issues/58
39 | lintOptions {
40 | abortOnError false
41 | warning 'InvalidPackage'
42 | }
43 | }
44 |
45 | repositories {
46 | google()
47 | jcenter()
48 | }
49 |
50 | dependencies {
51 | implementation 'com.facebook.react:react-native:+'
52 | implementation 'com.koushikdutta.async:androidasync:2.1.6'
53 | }
54 |
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | android.useAndroidX=true
2 | android.enableJetifier=true
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aprock/react-native-tcp/be5f656ffd3aa4559270e8472ee24a1c36029cf1/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.0.1-bin.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/android/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | #
4 | # Copyright 2015 the original author or authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 |
19 | ##############################################################################
20 | ##
21 | ## Gradle start up script for UN*X
22 | ##
23 | ##############################################################################
24 |
25 | # Attempt to set APP_HOME
26 | # Resolve links: $0 may be a link
27 | PRG="$0"
28 | # Need this for relative symlinks.
29 | while [ -h "$PRG" ] ; do
30 | ls=`ls -ld "$PRG"`
31 | link=`expr "$ls" : '.*-> \(.*\)$'`
32 | if expr "$link" : '/.*' > /dev/null; then
33 | PRG="$link"
34 | else
35 | PRG=`dirname "$PRG"`"/$link"
36 | fi
37 | done
38 | SAVED="`pwd`"
39 | cd "`dirname \"$PRG\"`/" >/dev/null
40 | APP_HOME="`pwd -P`"
41 | cd "$SAVED" >/dev/null
42 |
43 | APP_NAME="Gradle"
44 | APP_BASE_NAME=`basename "$0"`
45 |
46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
48 |
49 | # Use the maximum available, or set MAX_FD != -1 to use that value.
50 | MAX_FD="maximum"
51 |
52 | warn () {
53 | echo "$*"
54 | }
55 |
56 | die () {
57 | echo
58 | echo "$*"
59 | echo
60 | exit 1
61 | }
62 |
63 | # OS specific support (must be 'true' or 'false').
64 | cygwin=false
65 | msys=false
66 | darwin=false
67 | nonstop=false
68 | case "`uname`" in
69 | CYGWIN* )
70 | cygwin=true
71 | ;;
72 | Darwin* )
73 | darwin=true
74 | ;;
75 | MINGW* )
76 | msys=true
77 | ;;
78 | NONSTOP* )
79 | nonstop=true
80 | ;;
81 | esac
82 |
83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
84 |
85 | # Determine the Java command to use to start the JVM.
86 | if [ -n "$JAVA_HOME" ] ; then
87 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
88 | # IBM's JDK on AIX uses strange locations for the executables
89 | JAVACMD="$JAVA_HOME/jre/sh/java"
90 | else
91 | JAVACMD="$JAVA_HOME/bin/java"
92 | fi
93 | if [ ! -x "$JAVACMD" ] ; then
94 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
95 |
96 | Please set the JAVA_HOME variable in your environment to match the
97 | location of your Java installation."
98 | fi
99 | else
100 | JAVACMD="java"
101 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
102 |
103 | Please set the JAVA_HOME variable in your environment to match the
104 | location of your Java installation."
105 | fi
106 |
107 | # Increase the maximum file descriptors if we can.
108 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
109 | MAX_FD_LIMIT=`ulimit -H -n`
110 | if [ $? -eq 0 ] ; then
111 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
112 | MAX_FD="$MAX_FD_LIMIT"
113 | fi
114 | ulimit -n $MAX_FD
115 | if [ $? -ne 0 ] ; then
116 | warn "Could not set maximum file descriptor limit: $MAX_FD"
117 | fi
118 | else
119 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
120 | fi
121 | fi
122 |
123 | # For Darwin, add options to specify how the application appears in the dock
124 | if $darwin; then
125 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
126 | fi
127 |
128 | # For Cygwin or MSYS, switch paths to Windows format before running java
129 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
130 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
131 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
132 | JAVACMD=`cygpath --unix "$JAVACMD"`
133 |
134 | # We build the pattern for arguments to be converted via cygpath
135 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
136 | SEP=""
137 | for dir in $ROOTDIRSRAW ; do
138 | ROOTDIRS="$ROOTDIRS$SEP$dir"
139 | SEP="|"
140 | done
141 | OURCYGPATTERN="(^($ROOTDIRS))"
142 | # Add a user-defined pattern to the cygpath arguments
143 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
144 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
145 | fi
146 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
147 | i=0
148 | for arg in "$@" ; do
149 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
150 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
151 |
152 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
153 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
154 | else
155 | eval `echo args$i`="\"$arg\""
156 | fi
157 | i=`expr $i + 1`
158 | done
159 | case $i in
160 | 0) set -- ;;
161 | 1) set -- "$args0" ;;
162 | 2) set -- "$args0" "$args1" ;;
163 | 3) set -- "$args0" "$args1" "$args2" ;;
164 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
165 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
166 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
167 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
168 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
169 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
170 | esac
171 | fi
172 |
173 | # Escape application args
174 | save () {
175 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
176 | echo " "
177 | }
178 | APP_ARGS=`save "$@"`
179 |
180 | # Collect all arguments for the java command, following the shell quoting and substitution rules
181 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
182 |
183 | exec "$JAVACMD" "$@"
184 |
--------------------------------------------------------------------------------
/android/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
33 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
34 |
35 | @rem Find java.exe
36 | if defined JAVA_HOME goto findJavaFromJavaHome
37 |
38 | set JAVA_EXE=java.exe
39 | %JAVA_EXE% -version >NUL 2>&1
40 | if "%ERRORLEVEL%" == "0" goto init
41 |
42 | echo.
43 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
44 | echo.
45 | echo Please set the JAVA_HOME variable in your environment to match the
46 | echo location of your Java installation.
47 |
48 | goto fail
49 |
50 | :findJavaFromJavaHome
51 | set JAVA_HOME=%JAVA_HOME:"=%
52 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
53 |
54 | if exist "%JAVA_EXE%" goto init
55 |
56 | echo.
57 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
58 | echo.
59 | echo Please set the JAVA_HOME variable in your environment to match the
60 | echo location of your Java installation.
61 |
62 | goto fail
63 |
64 | :init
65 | @rem Get command-line arguments, handling Windows variants
66 |
67 | if not "%OS%" == "Windows_NT" goto win9xME_args
68 |
69 | :win9xME_args
70 | @rem Slurp the command line arguments.
71 | set CMD_LINE_ARGS=
72 | set _SKIP=2
73 |
74 | :win9xME_args_slurp
75 | if "x%~1" == "x" goto execute
76 |
77 | set CMD_LINE_ARGS=%*
78 |
79 | :execute
80 | @rem Setup the command line
81 |
82 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
83 |
84 | @rem Execute Gradle
85 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
86 |
87 | :end
88 | @rem End local scope for the variables with windows NT shell
89 | if "%ERRORLEVEL%"=="0" goto mainEnd
90 |
91 | :fail
92 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
93 | rem the _cmd.exe /c_ return code!
94 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
95 | exit /b 1
96 |
97 | :mainEnd
98 | if "%OS%"=="Windows_NT" endlocal
99 |
100 | :omega
101 |
--------------------------------------------------------------------------------
/android/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/android/src/main/java/com/peel/react/TcpSocketListener.java:
--------------------------------------------------------------------------------
1 | package com.peel.react;
2 |
3 | import java.net.InetSocketAddress;
4 |
5 | /**
6 | * Created by aprock on 12/28/15.
7 | */
8 | public interface TcpSocketListener {
9 | // server
10 | void onConnection(Integer serverId, Integer clientId, InetSocketAddress socketAddress);
11 |
12 | // client and server
13 | void onConnect(Integer id, InetSocketAddress socketAddress);
14 | void onData(Integer id, byte[] data);
15 | void onClose(Integer id, String error);
16 | void onError(Integer id, String error);
17 | }
18 |
--------------------------------------------------------------------------------
/android/src/main/java/com/peel/react/TcpSocketManager.java:
--------------------------------------------------------------------------------
1 | package com.peel.react;
2 |
3 | import androidx.annotation.Nullable;
4 | import android.util.SparseArray;
5 |
6 | import com.koushikdutta.async.AsyncNetworkSocket;
7 | import com.koushikdutta.async.AsyncServer;
8 | import com.koushikdutta.async.AsyncServerSocket;
9 | import com.koushikdutta.async.AsyncSocket;
10 | import com.koushikdutta.async.ByteBufferList;
11 | import com.koushikdutta.async.DataEmitter;
12 | import com.koushikdutta.async.Util;
13 | import com.koushikdutta.async.callback.CompletedCallback;
14 | import com.koushikdutta.async.callback.ConnectCallback;
15 | import com.koushikdutta.async.callback.DataCallback;
16 | import com.koushikdutta.async.callback.ListenCallback;
17 |
18 | import java.io.IOException;
19 | import java.lang.ref.WeakReference;
20 | import java.net.InetAddress;
21 | import java.net.InetSocketAddress;
22 | import java.net.UnknownHostException;
23 |
24 | /**
25 | * Created by aprock on 12/29/15.
26 | */
27 | public final class TcpSocketManager {
28 | private SparseArray