9

Simplified Peer to Peer Communication with PeerJS

 3 years ago
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.
neoserver,ios ssh client

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.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK