React Native TCP socket API for Android & iOS with SSL/TLS support
npm install react-native-tcp-socket
React Native TCP socket API for Android, iOS & macOS with SSL/TLS support. It allows you to create TCP client and server sockets, imitating Node's net and Node's tls API functionalities (check the available API for more information).
- Getting started
- Overriding net
- Overriding tls
- Using React Native \>= 0.60
- Self-Signed SSL (only available for React Native \> 0.60)
- Using React Native \< 0.60
- React Native Compatibility
- Usage
- Client example
- Server example
- TLS Client example
- TLS Server example
- API
- net
- Socket
- Server
- tls
- TLSSocket
- TLSServer
- Maintainers
- Acknowledgments
- License
```
yarn add react-native-tcp-socket
or npm:
``
npm install --save react-native-tcp-socket
#### Overriding netreact-native-tcp-socket
Since offers the same API as Node's net, in case you want to import this module as net or use require('net') in your JavaScript, you must add the following lines to your package.json file.
`json`
{
"react-native": {
"net": "react-native-tcp-socket"
}
}
In addition, in order to obtain the TS types (or autocompletion) provided by this module, you must also add the following to your custom declarations file.
`ts`
...
declare module 'net' {
import TcpSockets from 'react-native-tcp-socket';
export = TcpSockets;
}
If you want to avoid duplicated net types, make sure not to use the default node_modules/@types in your tsconfig.json "typeRoots" property.
_Check the example app provided for a working example._
#### Overriding tlstls
The same applies to module. However, you should be aware of the following:
* The Server class exported by default is non-TLS. In order to use the TLS server, you must use the TLSServer class. You may override the default Server class (tls.Server = tls.TLSServer). The same goes with the createServer() and connect(). In order to use the TLS methods, you must use the createTLSServer() and connectTLS() methods respectively. You may override the default methods (tls.createServer = tls.createTLSServer and tls.connect = tls.connectTLS).tls
* Node's module requires the keys and certificates to be provided as a string. However, the react-native-tcp-socket module requires them to be imported with require().
In addition, in order to obtain the TS types (or autocompletion) provided by this module, you must also add the following to your custom declarations file.
`ts`
...
declare module 'tls' {
import TcpSockets from 'react-native-tcp-socket';
export const Server = TcpSockets.TLSServer;
export const TLSSocket = TcpSockets.TLSSocket;
export const connect = TcpSockets.connectTLS;
export const createServer = TcpSockets.createTLSServer;
}
_Check the example app provided for a working example._
#### Using React Native >= 0.60
Linking the package manually is not required anymore with Autolinking.
- iOS Platform:
$ cd ios && pod install && cd .. # CocoaPods on iOS needs this extra step
- Android Platform:
Modify your android/build.gradle configuration to match minSdkVersion = 21:`
`
buildscript {
ext {
...
minSdkVersion = 21
...
}
#### Self-Signed SSL (only available for React Native > 0.60)
In order to generate the required files (keys and certificates) for self-signed SSL, you can use the following command:
``
openssl genrsa -out server-key.pem 4096
openssl req -new -key server-key.pem -out server-csr.pem
openssl x509 -req -in server-csr.pem -signkey server-key.pem -out server-cert.pem
openssl pkcs12 -export -out server-keystore.p12 -inkey server-key.pem -in server-cert.pemserver-keystore.p12
__Note:__ The must not have a password.
You will need a metro.config.js file in order to use a self-signed SSL certificate. You should already have this file in your root project directory, but if you don't, create it.
Inside a module.exports object, create a key called resolver with another object called assetExts. The value of assetExts should be an array of the resource file extensions you want to support.
If you want to be able to use .pem and .p12 files (plus all the already supported files), your metro.config.js should look like this:`javascript
const {getDefaultConfig} = require('metro-config');
const defaultConfig = getDefaultConfig.getDefaultValues(__dirname);
module.exports = {
resolver: {
assetExts: [...defaultConfig.resolver.assetExts, 'pem', 'p12'],
},
// ...
};
`
#### Using React Native < 0.60
You then need to link the native parts of the library for the platforms you are using. The easiest way to link the library is using the CLI tool by running this command from the root of your project:
$ react-native link react-native-tcp-socket
If you can't or don't want to use the CLI tool, you can also manually link the library using the instructions below (click on the arrow to show them):
Manually link the library on iOS
1. In XCode, in the project navigator, right click Libraries ➜ Add Files to [your project's name]node_modules
2. Go to ➜ react-native-tcp-socket and add TcpSockets.xcodeprojlibTcpSockets.a
3. In XCode, in the project navigator, select your project. Add to your project's Build Phases ➜ Link Binary With LibrariesCmd+R
4. Run your project ()<
Manually link the library on Android
1. Open up android/app/src/main/java/[...]/MainApplication.javaimport com.asterinet.react.tcpsocket.TcpSocketPackage;
- Add to the imports at the top of the filenew TcpSocketPackage()
- Add to the list returned by the getPackages() methodandroid/settings.gradle
2. Append the following lines to :`
`
include ':react-native-tcp-socket'
project(':react-native-tcp-socket').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-tcp-socket/android')
android/app/build.gradle
3. Insert the following lines inside the dependencies block in :`
`
implementation project(':react-native-tcp-socket')
you will need to upgrade before attempting to use the latest version.|
react-native-tcp-socket version | Required React Native Version |
| ---------------------------------- | ----------------------------- |
| 6.X.X, 5.X.X, 4.X.X, 3.X.X | >= 0.60.0 |
| 1.4.0 | >= Unknown |Usage
Import the library:
`javascript
import TcpSocket from 'react-native-tcp-socket';
// const net = require('react-native-tcp-socket');
// const tls = require('react-native-tcp-socket');
`
$3
`javascript
const options = {
port: port,
host: '127.0.0.1',
localAddress: '127.0.0.1',
reuseAddress: true,
// connectTimeout: 5000,
// localPort: 20000,
// interface: "wifi",
};// Create socket
const client = TcpSocket.createConnection(options, () => {
// Write on the socket
client.write('Hello server!');
// Close socket
client.destroy();
});
client.on('data', function(data) {
console.log('message was received', data);
});
client.on('error', function(error) {
console.log(error);
});
client.on('close', function(){
console.log('Connection closed!');
});
`$3
`javascript
const server = TcpSocket.createServer(function(socket) {
socket.on('data', (data) => {
socket.write('Echo server ' + data);
}); socket.on('error', (error) => {
console.log('An error ocurred with client socket ', error);
});
socket.on('close', (error) => {
console.log('Closed connection with ', socket.address());
});
}).listen({ port: 12345, host: '0.0.0.0' });
server.on('error', (error) => {
console.log('An error ocurred with the server', error);
});
server.on('close', () => {
console.log('Server closed connection');
});
`$3
`javascript
const options = {
port: port,
host: '127.0.0.1',
localAddress: '127.0.0.1',
reuseAddress: true,
// connectTimeout: 5000,
// localPort: 20000,
// interface: "wifi",
ca: require('server-cert.pem'),
};// Create socket
const client = TcpSocket.connectTLS(options, () => {
// Write on the socket
client.write('Hello server!');
// Close socket
client.destroy();
});
client.on('data', function(data) {
console.log('message was received', data);
});
client.on('error', function(error) {
console.log(error);
});
client.on('close', function(){
console.log('Connection closed!');
});
`$3
`javascript
const options = {
keystore: require('server-keystore.p12'),
};
const server = TcpSocket.createTLSServer(options, function(socket) {
socket.on('data', (data) => {
socket.write('Echo server ' + data);
});
socket.on('error', (error) => {
console.log('An error ocurred with SSL client socket ', error);
});
socket.on('close', (error) => {
console.log('SSL closed connection with ', socket.address());
});
}).listen({ port: 12345, host: '0.0.0.0' });
server.on('error', (error) => {
console.log('An error ocurred with the server', error);
});
server.on('close', () => {
console.log('Server closed connection');
});
`_Note: In order to use self-signed certificates make sure to update your metro.config.js configuration._
API
$3
Here are listed all methods implemented in react-native-tcp-socket that imitate Node's net API, their functionalities are equivalent to those provided by Node's net (more info on #41). However, the methods whose interface differs from Node are marked in bold.* [
net.connect(options[, callback])](#netcreateconnection----omit-in-toc)
* [net.createConnection(options[, callback])](#netcreateconnection----omit-in-toc)
* [net.createServer([options][, connectionListener])](https://nodejs.org/api/net.html#net_net_createserver_options_connectionlistener)
* net.isIP(input)
* net.isIPv4(input)
* net.isIPv6(input)address()
* [destroy([error])](https://nodejs.org/api/net.html#net_socket_destroy_error)
* [end([data][, encoding][, callback])](https://nodejs.org/api/net.html#net_socket_end_data_encoding_callback)
* [setEncoding([encoding])](https://nodejs.org/api/net.html#net_socket_setencoding_encoding)
* [setKeepAlive([enable][, initialDelay])](https://nodejs.org/api/net.html#net_socket_setkeepalive_enable_initialdelay) - _initialDelay is ignored_
* [setNoDelay([noDelay])](https://nodejs.org/api/net.html#net_socket_setnodelay_nodelay)
* [setTimeout(timeout[, callback])](https://nodejs.org/api/net.html#net_socket_settimeout_timeout_callback)
* [write(data[, encoding][, callback])](https://nodejs.org/api/net.html#net_socket_write_data_encoding_callback)
* pause()
* ref() - _Will not have any effect_
* resume()
* unref() - _Will not have any effect_
* Properties:
* Inherited from Stream.Writable:
* writableNeedDrain
* bytesRead
* bytesWritten
* connecting
* destroyed
* localAddress
* localPort
* remoteAddress
* remoteFamily
* remotePort
* pending
* timeout
* readyState
* Events:
* Inherited from Stream.Readable:
* 'pause'
* 'resume'
* 'close'
* 'connect'
* 'data'
* 'drain'
* 'error'
* 'timeout'#####
net.createConnection()
net.createConnection(options[, callback]) creates a TCP connection using the given options. The options parameter must be an object with the following properties:| Property | Type | iOS/macOS | Android | Description |
| -------------- | ----------- | :-------: | :-----: | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
port | | ✅ | ✅ | Required. Port the socket should connect to. |
| host | | ✅ | ✅ | Host the socket should connect to. IP address in IPv4 format or 'localhost'. Default: 'localhost'. |
| localAddress | | ✅ | ✅ | Local address the socket should connect from. If not specified, the OS will decide. It is highly recommended to specify a localAddress to prevent overload errors and improve performance. |
| localPort | | ✅ | ✅ | Local port the socket should connect from. If not specified, the OS will decide. |
| connectTimeout | | ✅ | ✅ | Connects the socket to a server with a configurable connection timeout (in milliseconds). If the timeout expires before the connection is established, the operation fails. When no timeout is specified, the connection will block indefinitely until it either succeeds or an error occurs. |
| interface | | ❌ | ✅ | Interface the socket should connect from. If not specified, it will use the current active connection. The options are: 'wifi', 'ethernet', 'cellular'. |
| reuseAddress | | ❌ | ✅ | Enable/disable the reuseAddress socket option. Default: true. |Note: The platforms marked as ❌ use the default value.
address()
* [listen(options[, callback])](#serverlisten----omit-in-toc)
* [close([callback])](https://nodejs.org/api/net.html#net_server_close_callback)
* getConnections(callback)
* Properties:
* listening
* Events:
* 'close'
* 'connection'
* 'error'
* 'listening'#####
Server.listen()
Server.listen(options[, callback]) creates a TCP server socket using the given options. The options parameter must be an object with the following properties:| Property | Type | iOS/macOS | Android | Description |
| -------------- | ----------- | :-------: | :-----: | ------------------------------------------------------------------------------------------------------- |
|
port | | ✅ | ✅ | Required. Port the socket should listen to. |
| host | | ✅ | ✅ | Host the socket should listen to. IP address in IPv4 format or 'localhost'. Default: '0.0.0.0'. |
| reuseAddress | | ❌ | ✅ | Enable/disable the reuseAddress socket option. Default: true. |Note: The platforms marked as ❌ use the default value.
$3
Here are listed all methods implemented in react-native-tcp-socket that imitate Node's tls API, their functionalities are equivalent to those provided by Node's tls. However, the methods whose interface differs from Node are marked in bold.* [
tls.connectTLS(options[, callback])](#tlsconnecttls----omit-in-toc)
* [tls.createTLSServer([options][, secureConnectionListener])](#tlscreatetlsserver----omit-in-toc)Socket
* getCertificate()
* getPeerCertificate()
* Properties:
* All properties from Socket
* Events:
* All events from Socket
* 'secureConnect'#####
tls.connectTLS()
tls.connectTLS(options[, callback]) creates a TLS socket connection using the given options. The options parameter must be an object with the following properties:| Property | Type | iOS/macOS | Android | Description |
| ----------------- | ---------------------- | :-------: | :-----: | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
ca | | ✅ | ✅ | CA file (.pem format) to trust. If null, it will use the device's default SSL trusted list. Useful for self-signed certificates. _Check the documentation for generating such file_. Default: null. |
| key | | ✅ | ✅ | Private key file (.pem format). _Check the documentation for generating such file_. |
| cert | | ✅ | ✅ | Public certificate file (.pem format). _Check the documentation for generating such file_. |
| androidKeyStore | | ❌ | ✅ | Android KeyStore alias. |
| certAlias | | ✅ | ✅ | Android KeyStore certificate alias. |
| keyAlias | | ✅ | ✅ | Android KeyStore private key alias. |
| ... | | ✅ | ✅ | Any other socket.connect() options not already listed. |#### TLSServer
__Note__: The TLS server is named
Server in Node's tls, but it is named TLSServer in react-native-tcp-socket in order to avoid confusion with the Server class.
* Methods:
* All methods from Server
* setSecureContext(options)
* Properties:
* All properties from Server
* Events:
* All events from Server
* 'secureConnection'#####
tls.createTLSServer()
tls.createTLSServer([options][, secureConnectionListener]) creates a new tls.TLSServer. The secureConnectionListener, if provided, is automatically set as a listener for the 'secureConnection' event. The options parameter must be an object with the following properties:| Property | Type | iOS/macOS | Android | Description |
| -------------- | ---------- | :-------: | :-----: | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
keystore | | ✅ | ✅ | Required. Key store in PKCS#12 format with the server certificate and private key. _Check the documentation for generating such file_. |Maintainers
Acknowledgments
* iOS part originally forked from @aprock react-native-tcp
* react-native-udp
License
The library is released under the MIT license. For more information see
LICENSE`.