Gathering detailed insights and metrics for react-native-simple-peer
Gathering detailed insights and metrics for react-native-simple-peer
Gathering detailed insights and metrics for react-native-simple-peer
Gathering detailed insights and metrics for react-native-simple-peer
mc-react-native-simple-peer
To building an exciting peer-to-peer WebRTC-based mobile Application
simple-p2p-webrtc
Simple WebRTC peer-to-peer connections in both React Native and React apps.
rn-steps-indicator
A simple react-native library component for a Step Indicator with custom styling using `react-native-reanimated` for introducing custom animations, in the manner we have it as a peer dependency, and implemented completely with `typescript`.
To building an exciting peer-to-peer WebRTC-based mobile Application
npm install react-native-simple-peer
Typescript
Module System
Node Version
NPM Version
TypeScript (81.63%)
Java (9.67%)
Objective-C (5.02%)
JavaScript (2.3%)
Ruby (0.89%)
Shell (0.23%)
C (0.16%)
Swift (0.1%)
Total Downloads
0
Last Day
0
Last Week
0
Last Month
0
Last Year
0
MIT License
8 Stars
12 Commits
4 Forks
1 Watchers
1 Branches
1 Contributors
Updated on May 25, 2025
Latest Version
0.1.5
Package Id
react-native-simple-peer@0.1.5
Unpacked Size
279.32 kB
Size
63.26 kB
File Count
21
NPM Version
8.5.5
Node Version
16.15.0
Cumulative downloads
Total Downloads
Last Day
0%
NaN
Compared to previous day
Last Week
0%
NaN
Compared to previous week
Last Month
0%
NaN
Compared to previous month
Last Year
0%
NaN
Compared to previous year
3
21
To building Simple WebRTC video, voice, and data channels through peer-to-peer WebRTC-based mobile Application
1npm install react-native-simple-peer
1 yarn add react-native-simple-peer
This example create two peers in the same page.
1import RNSimplePeer from "react-native-simple-peer"; 2import { mediaDevices, RTCPeerConnection, RTCIceCandidate, RTCSessionDescription, } from "react-native-webrtc" 3 4const peer1 = new RNSimplePeer({ initiator: true, webRTC: { RTCPeerConnection, RTCIceCandidate, RTCSessionDescription }) 5const peer2 = new RNSimplePeer({ webRTC: { RTCPeerConnection, RTCIceCandidate, RTCSessionDescription } }) 6 7peer1.on('signal', data => { 8 // when peer1 has signaling data, give it to peer2 somehow 9 peer2.signal(data) 10}) 11 12peer2.on('signal', data => { 13 // when peer2 has signaling data, give it to peer1 somehow 14 peer1.signal(data) 15}) 16 17peer1.on('connect', () => { 18 // wait for 'connect' event before using the data channel 19 peer1.send('hey peer2, how is it going?') 20}) 21 22peer2.on('data', data => { 23 // got a data channel message 24 console.log('got a message from peer1: ' + data) 25})
Video/voice is also super simple! In this example, peer1 sends video to peer2.
1import RNSimplePeer from "react-native-simple-peer"; 2import { mediaDevices, RTCPeerConnection, RTCIceCandidate, RTCSessionDescription, } from "react-native-webrtc" 3 4// get video/voice stream 5 mediaDevices.getUserMedia({ 6 audio: true, 7 video: { 8 width: 640, 9 height: 480, 10 frameRate: 30, 11 facingMode: "user", 12 deviceId: videoSourceId 13 } 14 }).then(gotMedia).catch(() => {}) 15 16function gotMedia (stream) { 17 var peer1 = new RNSimplePeer({ initiator: true, stream: stream, webRTC: { RTCPeerConnection, RTCIceCandidate, RTCSessionDescription } }); 18 19 var peer2 = new RNSimplePeer({ webRTC: { RTCPeerConnection, RTCIceCandidate, RTCSessionDescription } }) 20 21 peer1.on('signal', data => { 22 peer2.signal(data) 23 }) 24 25 peer2.on('signal', data => { 26 peer1.signal(data) 27 }) 28 29 peer2.on('stream', stream => { 30 // got remote video stream, now let's show it in a video tag 31 let peerStream = stream 32 if (stream.currentTarget && stream.currentTarget._remoteStreams) { 33 peerStream = stream.currentTarget._remoteStreams[0]; 34 } 35 }) 36}
For two-way video, simply pass a stream
option into both Peer
constructors. Simple!
key props | type | defualts | descriptions |
---|---|---|---|
initiator | boolean | false | set to true if this is the initiating peer |
channelConfig | RTCDataChannelInit/undefined | {} | custom webrtc data channel configuration |
channelName | string/undefined | Random String | custom webrtc data channel name |
config | RTCConfiguration/undefined | { iceServers: [ { urls: [ 'stun:stun.l.google.com:19302', 'stun:global.stun.twilio.com:3478'] } ], sdpSemantics: 'unified-plan'} | custom webrtc configuration |
offerOptions | RTCOfferOptions/undefined | {} | custom offer options |
answerOptions | RTCAnswerOptions/undefined | {} | custom answer options |
sdpTransform | Function | (instance, sdp) => {} | function to transform the generated SDP signaling data |
streams | Array | undefined | video/voice streams |
stream | MediaStream/undefined | undefined | video/voice stream |
trickle | boolean | false | set to false to disable trickle ICE and get a single 'signal' event |
allowHalfTrickle | boolean | false | determines how long to wait before providing an offer or answer |
iceCompleteTimeout | number | 5000 | how long to wait before providing an offer or answer |
debugConsole | boolean | true | to show debug console |
webRTC | Object | {RTCIceCandidate, RTCPeerConnection, RTCSessionDescription} | Set Webrtc classess |
Method | descriptions |
---|---|
peer.signal(data) | Call this method whenever the remote peer emits a peer.on('signal') event. The data will encapsulate a webrtc offer, answer, or ice candidate. |
peer.send(data) | Send text/binary data to the remote peer. |
peer.addStream(stream) | Add a MediaStream to the connection. |
peer.removeStream(stream) | Remove a MediaStream from the connection. |
peer.addTrack(track, stream) | Add a MediaStreamTrack to the connection. Must also pass the MediaStream you want to attach it to. |
peer.removeTrack(track, stream) | Remove a MediaStreamTrack from the connection. Must also pass the MediaStream that it was attached to. |
peer.replaceTrack(oldTrack, newTrack, stream) | Replace a MediaStreamTrack with another track. Must also pass the MediaStream that the old track was attached to. |
peer.addTransceiver(kind, init) | Add a RTCRtpTransceiver to the connection. Can be used to add transceivers before adding tracks. Automatically called addTrack. |
peer.destroy([err]) | Destroy and cleanup If the optional err parameter is passed, then it will be emitted as an 'error' event on the stream. |
Event | descriptions |
---|---|
peer.removeAllListeners('close') | removing all registered close-event listeners |
peer.on('signal', data => {}) | Fired when the peer wants to send signaling data to the remote peer. |
peer.on('connect', () => {}) | Fired when the peer connection and data channel are ready to use. |
peer.on('data', data => {}) | Received a message from the remote peer (via the data channel). |
peer.on('stream', stream => {}) | Received a remote video stream |
peer.on('track', (track, stream) => {}) | Received a remote audio/video track. Streams may contain multiple tracks. |
peer.on('close', () => {}) | Called when the peer connection has closed. |
peer.on('error', (err) => {}) | Fired when a fatal error occurs. Usually, this means bad signaling data was received from the remote peer. |
Peer
objects are instances of stream.Duplex
. They behave very similarly to a
net.Socket
from the node core net
module. The duplex stream reads/writes to the data
channel.
1var peer = new RNSimplePeer(props) 2// ... signaling ... 3peer.write(new Buffer('hey')) 4peer.on('data', function (chunk) { 5 console.log('got a chunk', chunk) 6})
Errors returned by the error
event have an err.code
property that will indicate the origin of the failure.
Possible error codes:
ERR_WEBRTC_SUPPORT
ERR_CREATE_OFFER
ERR_CREATE_ANSWER
ERR_SET_LOCAL_DESCRIPTION
ERR_SET_REMOTE_DESCRIPTION
ERR_ADD_ICE_CANDIDATE
ERR_ICE_CONNECTION_FAILURE
ERR_SIGNALING
ERR_DATA_CHANNEL
ERR_CONNECTION_FAILURE
The simplest way to do that is to create a full-mesh topology. That means that every peer opens a connection to every other peer. To illustrate:
To broadcast a message, just iterate over all the peers and call peer.send
.
So, say you have 3 peers. Then, when a peer wants to send some data it must send it 2 times, once to each of the other peers. So you're going to want to be a bit careful about the size of the data you send.
Full mesh topologies don't scale well when the number of peers is very large. The total
number of edges in the network will be
where
n
is the number of peers.
For clarity, here is the code to connect 3 peers together:
1// These are peer1's connections to peer2 and peer3 2var peer2 = new RNSimplePeer({ initiator: true, webRTC: { RTCPeerConnection, RTCIceCandidate, RTCSessionDescription } }) 3var peer3 = new RNSimplePeer({ initiator: true, webRTC: { RTCPeerConnection, RTCIceCandidate, RTCSessionDescription } }) 4 5peer2.on('signal', data => { 6 // send this signaling data to peer2 somehow 7}) 8 9peer2.on('connect', () => { 10 peer2.send('hi peer2, this is peer1') 11}) 12 13peer2.on('data', data => { 14 console.log('got a message from peer2: ' + data) 15}) 16 17peer3.on('signal', data => { 18 // send this signaling data to peer3 somehow 19}) 20 21peer3.on('connect', () => { 22 peer3.send('hi peer3, this is peer1') 23}) 24 25peer3.on('data', data => { 26 console.log('got a message from peer3: ' + data) 27})
1// These are peer2's connections to peer1 and peer3 2var peer1 = new RNSimplePeer({ webRTC: { RTCPeerConnection, RTCIceCandidate, RTCSessionDescription } }) 3var peer3 = new RNSimplePeer({ initiator: true, webRTC: { RTCPeerConnection, RTCIceCandidate, RTCSessionDescription } }) 4 5peer1.on('signal', data => { 6 // send this signaling data to peer1 somehow 7}) 8 9peer1.on('connect', () => { 10 peer1.send('hi peer1, this is peer2') 11}) 12 13peer1.on('data', data => { 14 console.log('got a message from peer1: ' + data) 15}) 16 17peer3.on('signal', data => { 18 // send this signaling data to peer3 somehow 19}) 20 21peer3.on('connect', () => { 22 peer3.send('hi peer3, this is peer2') 23}) 24 25peer3.on('data', data => { 26 console.log('got a message from peer3: ' + data) 27})
1// These are peer3's connections to peer1 and peer2 2var peer1 = new RNSimplePeer({webRTC: { RTCPeerConnection, RTCIceCandidate, RTCSessionDescription } }) 3var peer2 = new RNSimplePeer({webRTC: { RTCPeerConnection, RTCIceCandidate, RTCSessionDescription } }) 4 5peer1.on('signal', data => { 6 // send this signaling data to peer1 somehow 7}) 8 9peer1.on('connect', () => { 10 peer1.send('hi peer1, this is peer3') 11}) 12 13peer1.on('data', data => { 14 console.log('got a message from peer1: ' + data) 15}) 16 17peer2.on('signal', data => { 18 // send this signaling data to peer2 somehow 19}) 20 21peer2.on('connect', () => { 22 peer2.send('hi peer2, this is peer3') 23}) 24 25peer2.on('data', data => { 26 console.log('got a message from peer2: ' + data) 27})
If you call peer.send(buf)
, simple-peer
is not keeping a reference to buf
and sending the buffer at some later point in time. We immediately call
channel.send()
on the data channel. So it should be fine to mutate the buffer
right afterward.
However, beware that peer.write(buf)
(a writable stream method) does not have
the same contract. It will potentially buffer the data and call
channel.send()
at a future point in time, so definitely don't assume it's
safe to mutate the buffer.
If a direct connection fails, in particular, because of NAT traversal and/or firewalls, WebRTC ICE uses an intermediary (relay) TURN server. In other words, ICE will first use STUN with UDP to directly connect peers and, if that fails, will fall back to a TURN relay server.
In order to use a TURN server, you must specify the config
option to the Peer
constructor. See the API docs above.
See the contributing guide to learn how to contribute to the repository and the development workflow.
MIT
No vulnerabilities found.
No security vulnerabilities found.