react-native-tcp-socket-polling
v6.3.6
Published
React Native TCP socket API for Android & iOS with SSL/TLS and polling support
Downloads
49
Maintainers
Readme
react-native-tcp-socket with Polling Support
Fork of react-native-tcp-socket with native polling write functionality.
React Native TCP socket API for Android, iOS & macOS with SSL/TLS support and native polling writes. It allows you to create TCP client and server sockets, imitating Node's net and Node's tls API functionalities, plus additional polling functionality to prevent JavaScript thread blocking (check the available API for more information).
Table of Contents
- Getting started
- React Native Compatibility
- Usage
- Polling Write Functionality
- API
- Maintainers
- Acknowledgments
- License
Getting started
Install the library using either Yarn:
yarn add react-native-tcp-socket-pollingor npm:
npm install --save react-native-tcp-socket-pollingOverriding net
Since react-native-tcp-socket-polling 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.
{
"react-native": {
"net": "react-native-tcp-socket-polling"
}
}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.
...
declare module 'net' {
import TcpSockets from 'react-native-tcp-socket-polling';
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 tls
The same applies to tls module. However, you should be aware of the following:
- The
Serverclass exported by default is non-TLS. In order to use the TLS server, you must use theTLSServerclass. You may override the defaultServerclass (tls.Server = tls.TLSServer). The same goes with thecreateServer()andconnect(). In order to use the TLS methods, you must use thecreateTLSServer()andconnectTLS()methods respectively. You may override the default methods (tls.createServer = tls.createTLSServerandtls.connect = tls.connectTLS). - Node's
tlsmodule requires the keys and certificates to be provided as a string. However, thereact-native-tcp-socketmodule requires them to be imported withrequire().
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.
...
declare module 'tls' {
import TcpSockets from 'react-native-tcp-socket-polling';
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 stepAndroid Platform:
Modify your
android/build.gradleconfiguration to matchminSdkVersion = 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.pemNote: The server-keystore.p12 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:
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-polling
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):
- In XCode, in the project navigator, right click
Libraries➜Add Files to [your project's name] - Go to
node_modules➜react-native-tcp-socket-pollingand addTcpSockets.xcodeproj - In XCode, in the project navigator, select your project. Add
libTcpSockets.ato your project'sBuild Phases➜Link Binary With Libraries - Run your project (
Cmd+R)<
- Open up
android/app/src/main/java/[...]/MainApplication.java
- Add
import com.asterinet.react.tcpsocket.TcpSocketPackage;to the imports at the top of the file - Add
new TcpSocketPackage()to the list returned by thegetPackages()method
- Append the following lines to
android/settings.gradle:include ':react-native-tcp-socket-polling' project(':react-native-tcp-socket-polling').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-tcp-socket-polling/android') - Insert the following lines inside the dependencies block in
android/app/build.gradle:implementation project(':react-native-tcp-socket-polling')
React Native Compatibility
To use this library you need to ensure you are using the correct version of React Native. If you are using a version of React Native that is lower than 0.60 you will need to upgrade before attempting to use the latest version.
| react-native-tcp-socket-polling version | Required React Native Version |
| ---------------------------------- | ----------------------------- |
| 6.X.X | >= Unknown |
Usage
Import the library:
import TcpSocket from 'react-native-tcp-socket';
// const net = require('react-native-tcp-socket');
// const tls = require('react-native-tcp-socket');Client example
const options = {
port: port,
host: '127.0.0.1',
localAddress: '127.0.0.1',
reuseAddress: true,
// 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!');
});Server example
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');
});TLS Client example
const options = {
port: port,
host: '127.0.0.1',
localAddress: '127.0.0.1',
reuseAddress: true,
// 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!');
});
TLS Server example
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.
Polling Write example
const client = TcpSocket.createConnection(options, async () => {
// Start polling write - send heartbeat every 1000ms (1 second)
try {
const intervalId = await client.startPollingWrite(1000, 'ping\n', 'utf8');
console.log(`Started polling write with interval ID: ${intervalId}`);
// Update the message after 2 seconds
setTimeout(async () => {
console.log('Updating polling message...');
const updated = await client.updatePollingMessage(intervalId, 'pong\n', 'utf8');
console.log(`Message updated: ${updated}`);
}, 2000);
// Update with precise timing after 3 seconds
setTimeout(async () => {
console.log('Updating with precise timing...');
const updated = await client.updatePollingMessage(intervalId, 'urgent\n', 200, 'utf8');
console.log(`Precise update: ${updated}`);
}, 3000);
// Stop polling after 5 seconds
setTimeout(async () => {
console.log('Stopping polling write...');
const stopped = await client.stopPollingWrite(intervalId);
console.log(`Polling write stopped: ${stopped}`);
client.destroy();
}, 5000);
} catch (error) {
console.error('Error with polling write:', error);
}
});Polling Write Functionality
This fork adds native polling write functionality that allows you to repeatedly send data at specified intervals without blocking the JavaScript thread. The polling logic runs entirely in native code (iOS/Android) for optimal performance.
Key Features:
- Native Performance: All polling logic runs in native code to prevent JS thread freezes
- Cross-Platform: Works identically on both iOS and Android
- Memory Safe: Automatic cleanup when sockets are destroyed
- Unique IDs: Each polling operation gets a unique identifier for precise control
- Promise-based: Modern async/await compatible API
Use Cases:
- Heartbeat/keepalive messages
- Periodic status updates
- Real-time data streaming
- Connection monitoring
New Methods:
startPollingWrite(interval, data[, encoding][, callback])- Start polling write operationstopPollingWrite(intervalId[, callback])- Stop specific polling operationupdatePollingMessage(intervalId, data[, firstDelayMs][, encoding][, callback])- Update polling data without restarting
API
net
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])net.createConnection(options[, callback])net.createServer([options][, connectionListener])net.isIP(input)net.isIPv4(input)net.isIPv6(input)
Socket
- Methods:
address()destroy([error])end([data][, encoding][, callback])setEncoding([encoding])setKeepAlive([enable][, initialDelay])-initialDelayis ignoredsetNoDelay([noDelay])setTimeout(timeout[, callback])write(data[, encoding][, callback])startPollingWrite(interval, data[, encoding][, callback])- Native polling writestopPollingWrite(intervalId[, callback])- Stop native polling writeupdatePollingMessage(intervalId, data[, firstDelayMs][, encoding][, callback])- Update polling data without restartingpause()ref()- Will not have any effectresume()unref()- Will not have any effect
- Properties:
- Events:
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 | <number> | ✅ | ✅ | Required. Port the socket should connect to. |
| host | <string> | ✅ | ✅ | Host the socket should connect to. IP address in IPv4 format or 'localhost'. Default: 'localhost'. |
| localAddress | <string> | ✅ | ✅ | 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 | <number> | ✅ | ✅ | Local port the socket should connect from. If not specified, the OS will decide. |
| interface | <string> | ❌ | ✅ | Interface the socket should connect from. If not specified, it will use the current active connection. The options are: 'wifi', 'ethernet', 'cellular'. |
| reuseAddress | <boolean> | ❌ | ✅ | Enable/disable the reuseAddress socket option. Default: true. |
Note: The platforms marked as ❌ use the default value.
socket.startPollingWrite()
socket.startPollingWrite(interval, data[, encoding][, callback]) starts a polling write operation that repeatedly sends data at specified intervals. This operation runs in native code to prevent JavaScript thread blocking.
Parameters:
interval<number>- Required. Interval in milliseconds between writes.data<string> | <Buffer> | <Uint8Array>- Required. Data to be sent repeatedly.encoding<string>- Encoding if data is a string. Default:'utf8'.callback<function>- Optional callback function called when operation starts or fails.
Returns: <Promise<string>> - Promise that resolves to interval ID that can be used to stop the polling.
Example:
const intervalId = await socket.startPollingWrite(1000, 'heartbeat\n', 'utf8');
console.log('Started polling with ID:', intervalId);socket.stopPollingWrite()
socket.stopPollingWrite(intervalId[, callback]) stops a specific polling write operation.
Parameters:
intervalId<string>- Required. The interval ID returned bystartPollingWrite().callback<function>- Optional callback function called when operation completes.
Returns: <Promise<boolean>> - Promise that resolves to true if the interval was found and stopped, false otherwise.
Example:
const stopped = await socket.stopPollingWrite(intervalId);
console.log('Polling stopped:', stopped);socket.updatePollingMessage()
socket.updatePollingMessage(intervalId, data[, firstDelayMs][, encoding][, callback]) updates the data being sent by an existing polling write operation without restarting the timer. This allows for dynamic message updates while maintaining precise timing.
Parameters:
intervalId<string>- Required. The interval ID returned bystartPollingWrite().data<string> | <Buffer> | <Uint8Array>- Required. New data to be sent repeatedly.firstDelayMs<number>- Optional. Delay in milliseconds for the first updated message. If provided, the first updated message will be sent at the nearest aligned time based on the last sent message and this delay.encoding<string>- Encoding if data is a string. Default:'utf8'.callback<function>- Optional callback function called when operation completes.
Returns: <Promise<boolean>> - Promise that resolves to true if the interval was found and data was updated, false otherwise.
Smart Timing Logic:
- If
firstDelayMsis not provided, the data is updated for the next scheduled send - If
firstDelayMsis provided, the system calculates the optimal send time:- If target time >= next normal tick: Skip sending (normal timer will handle it)
- If target time < next normal tick and in the past: Add delays and validate
- If target time < next normal tick and in the future: Send at calculated time
Example:
// Update data without timing control
const updated = await socket.updatePollingMessage(intervalId, 'new heartbeat\n', 'utf8');
// Update data with precise timing control
const updated = await socket.updatePollingMessage(intervalId, 'urgent update\n', 500, 'utf8');
console.log('Data updated:', updated);Server
- Methods:
- Properties:
- Events:
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 | <number> | ✅ | ✅ | Required. Port the socket should listen to. |
| host | <string> | ✅ | ✅ | Host the socket should listen to. IP address in IPv4 format or 'localhost'. Default: '0.0.0.0'. |
| reuseAddress | <boolean> | ❌ | ✅ | Enable/disable the reuseAddress socket option. Default: true. |
Note: The platforms marked as ❌ use the default value.
tls
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.
TLSSocket
- Methods:
- All methods from
Socket(includingstartPollingWrite,stopPollingWrite, andupdatePollingMessage) getCertificate()getPeerCertificate()
- All methods from
- Properties:
- All properties from
Socket
- All properties from
- Events:
- All events from
Socket 'secureConnect'
- All events from
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 | <import> | ✅ | ✅ | 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 | <import> \| <string> | ✅ | ✅ | Private key file (.pem format). Check the documentation for generating such file. |
| cert | <import> \| <string> | ✅ | ✅ | Public certificate file (.pem format). Check the documentation for generating such file. |
| androidKeyStore | <string> | ❌ | ✅ | Android KeyStore alias. |
| certAlias | <string> | ✅ | ✅ | Android KeyStore certificate alias. |
| keyAlias | <string> | ✅ | ✅ | Android KeyStore private key alias. |
| ... | <any> | ✅ | ✅ | 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)
- All methods from
- Properties:
- All properties from
Server
- All properties from
- Events:
- All events from
Server 'secureConnection'
- All events from
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 | <import> | ✅ | ✅ | 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.
