Simplified Peer to Peer Communication with PeerJS
source link: https://blog.bitsrc.io/simplified-peer-to-peer-communication-with-peerjs-e37244267723
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Building Your First Chat Room with PeerJS and React
Step 1 — Installing PeerJS
First, we need to install PeerJS library to your project as a node module and the peer library as a global dependency.
// Installing PeerJS
npm i peerjs// Installing Peer
npm i -g peer
Note: PeerJS library is used to start the PeerServer locally. You can also use the PeerServer Cloud instance as well.
Step 2 — Implementing the Chat Room
Now, let’s move to our React application and get things started by initializing the state of the chat component.
Inside the state, we will be handling our ID, peer ID, chat messages, and an instance of Peer object.
state = {
myId: '',
friendId: '',
peer: {},
message: '',
messages: []
}
Then we need to create a Peer instance by defining hostname, port, and path to manage our P2P connection. We will use this instance throughout the communication process.
const peer = new Peer('', {
host: 'localhost',
port: '3001',
path: '/'
});
Tip: You can use your own ID as the first argument or leave it undefined for the PeerServer to generate a random ID. If you use
const peer = new Peer();
you will be connected to PeerServer Cloud.
Peer instance has several methods to handle communication between peers. peer.on
is used to listen to peer events, and it is useful when receiving calls from remote peers.
open
event will be emitted after successfully connecting to PeerServer, and we will use this event to update the state of myId and peer instance.
peer.on('open', (id) => {this.setState({
myId: id,
peer: peer
});
});
Then, we need to use the connection
event to listen to remote peer connections, and we can use its callback to grab the message sent by the remote peer.
peer.on('connection', (conn) => {
conn.on('data', (data) => { this.setState({
messages: [...this.state.messages, data]
}); });
});
Now, we have implemented all the functionalities to receive messages. As the final step, let’s create a method to send a message.
peer.connect
method allows us to connect to the peer by specifying peer id. Then it returns a DataConnection
object which can be used to send message data to the peer.
send = () => {
const conn = this.state.peer.connect(this.state.friendId); conn.on('open', () => { const msgObj = {
sender: this.state.myId,
message: this.state.message
}; conn.send(msgObj); this.setState({
messages: [...this.state.messages, msgObj],
message: ''
}); });
}
Step 3 — Video Chat Implementation
Now, let’s modify our chat room to send video messages. Implementing it is pretty much similar to what we discussed in the previous step. We can use the call
event inside peer.on
method to listen to calls from the remote peer. It will provide a callback with an object named MediaConnection
and receiver’s video and audio streams are provided to the answer
method of MediaConnection
object.
peer.on('call', (call) => {var getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;getUserMedia({ video: true, audio: true }, (stream) => { this.myVideo.srcObject = stream;
this.myVideo.play();
call.answer(stream); call.on('stream', (remoteStream) => {
this.friendVideo.srcObject = remoteStream;
this.friendVideo.play();
});}, err => { console.log('Error!') });
});
Now let’s make a video call to the peer from our end. This approach is similar to answering a call. We need to use the call
method of the initial peer
instance and provide peer ID and video stream as arguments.
call
method will then return a MediaConnection
object which we can use to access the peer’s stream.
videoCall = () => {var getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;getUserMedia({ video: true, audio: true }, (stream) => { this.myVideo.srcObject = stream;
this.myVideo.play(); const call = this.state.peer.call(this.state.friendId, stream); call.on('stream', (remoteStream) => {
this.friendVideo.srcObject = remoteStream;
this.friendVideo.play();
});
}, err => { console.log('Error!') });
}
Step 4 — Finalizing Things
Finally, it’s time to add some JSX to render our chat room. Let’s add two input fields for peer ID and chat messages. We will use the ref
attribute to access the video
element.
return (
<div className="wrapper">
<div className="col">
<h1>My ID: {this.state.myId}</h1> <label>Friend ID:</label>
<input
type="text"
value={this.state.friendId}
onChange={e => { this.setState({ friendId: e.target.value });}} /><br />
<br /> <label>Message:</label>
<input
type="text"
value={this.state.message}
onChange={e => { this.setState({ message: e.target.value }); }} /> <button onClick={this.send}>Send</button>
<button onClick={this.videoCall}>Video Call</button>
{
this.state.messages.map((message, i) => {
return (
<div key={i}>
<h3>{message.sender}:</h3>
<p>{message.message}</p>
</div>
)
});
}
</div>
<div className="col">
<div>
<video ref={ref => this.myVideo = ref} />
</div>
<div>
<video ref={ref => this.friendVideo = ref} />
</div>
</div>
</div>
);
That’s it! Now we are all set for a quick video chat. The final implementation will look like this and you can find the full code in my GitHub repository.
Note: Some browsers (especially mobile browsers) may not allow camera and microphone access without an HTTPS connection. You can refer to this article to set up a local HTTPS connection in few steps.
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK