So erstellen Sie eine Video-Chat-Anwendung mit React, Node.js und Twilio

Blog

So erstellen Sie eine Video-Chat-Anwendung mit React, Node.js und Twilio

So erstellen Sie eine Video-Chat-Anwendung mit React, Node.js und Twilio

Einführung

Twilio ist ein Cloud-Kommunikationsplattform-as-a-Service-Unternehmen mit Sitz in San Francisco, Kalifornien. Twilio ermöglicht es Softwareentwicklern, programmgesteuert Telefonanrufe zu tätigen und zu empfangen, Textnachrichten zu senden und zu empfangen und andere Kommunikationsfunktionen mithilfe seiner Webdienst-APIs auszuführen.

Programmierbares Video

Programmierbares Video ist der von Twilio bereitgestellte Dienst, der mehrere Benutzer (begrenzt) in einer einzigen Videokonferenz verbindet, sodass diese Benutzer über die Live-Konferenz oder den Laufzeit-Video-Chat miteinander interagieren können.

Warum hat die Cash-App mein Konto geschlossen?

Schritt 1 – Node.Js-Anwendung erstellen

Node js-Code wird für API-Aufrufe verwendet, um den Benutzer zu authentifizieren und erhält im Gegenzug ein Token des Benutzers. Nachdem wir verschiedene benutzerspezifische Token erhalten haben, können wir uns mit demselben von Twilio erstellten Raum verbinden, um eine Videokonferenz zu machen.

require('dotenv').load() const express = require('express') const app = express() var AccessToken = require('twilio').jwt.AccessToken; var VideoGrant = AccessToken.VideoGrant; app.get('/token/:identity', function (req, res) { const identity = req.params.identity; // Create an access token which we will sign and return to the client, // containing the grant we just created var token = new AccessToken( process.env.TWILIO_ACCOUNT_SID, process.env.TWILIO_API_KEY, process.env.TWILIO_API_SECRET ); // Assign the generated identity to the token token.identity = identity; const grant = new VideoGrant(); // Grant token access to the Video API features token.addGrant(grant); // Serialize the token to a JWT string and include it in a JSON response res.send({ identity: identity, jwt: token.toJwt() }) }) app.listen(3001, function () { console.log('Programmable Video Chat token server listening on port 3001!') })

Schritt 2 - Erstellen Sie die React.Js-Anwendung

Konfigurierte grundlegende ReactJs-Anwendung mit dem Befehl create-react-app. Mit diesem Befehl erhalten Sie die standardmäßige gut strukturierte Anwendung von React.

Das ist der Bildtitel

Schritt 3 - Twilio-Konfiguration

Wenn Sie kein Konto bei Twilio haben, können Sie sich anmelden ( Registrieren ), dann konfigurieren Sie Ihr Konto.

Das ist der Bildtitel

Ihre(n) Konfigurationsschlüssel erhalten Sie von:

  • TWILIO_ACCOUNT_SID: Rufen Sie TWILIO_ACCOUNT_SID vom Twilio-Konto auf Armaturenbrett.

Das ist der Bildtitel

Gehen Sie im programmierbaren Video-Dashboard des Twilio-Kontos zu TWILIO_API_KEY && TWILIO_API_SECRET.

Das ist der Bildtitel

  • Lassen Sie uns unsere .env-Datei erstellen und den folgenden Code hinzufügen, indem wir jeden Schlüssel und jedes Token durch den in unserer Twilio-Konsole ersetzen.

Das ist der Bildtitel

Klassenname des nächsten js-Links

Twilio-Code - Vordefinierte Funktionen (App.js)

import React, { Component } from 'react' import Video from 'twilio-video'; import axios from 'axios'; import './global.css'; import { ToastsContainer, ToastsStore } from 'react-toasts'; import 'react-loader-spinner/dist/loader/css/react-spinner-loader.css'; import Loader from 'react-loader-spinner'; class App extends Component { constructor(props) { super(props); this.state = { userName: '', identity: null, peerUserId: 0, peerIdentity: '', roomName: '*****', // Room Name roomNameErr: false, // Track error for room name TextField previewTracks: null, localMediaAvailable: false, hasJoinedRoom: false, hasParticipantsJoinedRoom: false, activeRoom: '', // Track the current active room jwt: '' } this.joinRoom = this.joinRoom.bind(this); this.roomJoined = this.roomJoined.bind(this); this.leaveRoom = this.leaveRoom.bind(this); this.detachTracks = this.detachTracks.bind(this); this.detachParticipantTracks = this.detachParticipantTracks.bind(this); } getTwillioToken = () => { const currentUserName = this.refs['yourname'].value; if (currentUserName.length === 0) { ToastsStore.error('Please enter the username!'); return; } axios.get('/token/' + currentUserName).then(results => { const { identity, jwt } = results.data; this.setState( { identity, jwt }, () => { if (jwt.length === 0 || identity.length === 0) { ToastsStore.error('Issue to fetch token!'); } else { this.setState({ userName: currentUserName }); this.joinRoom(); } }); }); } joinRoom() { if (!this.state.roomName.trim()) { this.setState({ roomNameErr: true }); return; } console.log('Joining room '' + this.state.roomName + ''...'); let connectOptions = { name: this.state.roomName }; if (this.state.previewTracks) { connectOptions.tracks = this.state.previewTracks; } // Join the Room with the token from the server and the // LocalParticipant's Tracks. Video.connect(this.state.jwt, connectOptions).then(this.roomJoined, error => { ToastsStore.error('Please verify your connection of webcam!'); ToastsStore.error('Webcam-Video permission should not block!'); }); } attachTracks(tracks, container) { tracks.forEach(track => { container.appendChild(track.attach()); }); } // Attaches a track to a specified DOM container attachParticipantTracks(participant, container) { var tracks = Array.from(participant.tracks.values()); this.attachTracks(tracks, container); } detachTracks(tracks) { tracks.forEach(track => { track.detach().forEach(detachedElement => { detachedElement.remove(); }); }); } detachParticipantTracks(participant) { var tracks = Array.from(participant.tracks.values()); this.detachTracks(tracks); } roomJoined(room) { // Called when a participant joins a room console.log('Joined as '' + this.state.identity + '''); this.setState({ activeRoom: room, localMediaAvailable: true, hasJoinedRoom: true }); // Attach LocalParticipant's Tracks, if not already attached. var previewContainer = this.refs.groupChat_localMedia; console.log('previewContainer.querySelector(video)', previewContainer.querySelector('.video')); if (!previewContainer.querySelector('.video')) { this.attachParticipantTracks(room.localParticipant, this.refs.groupChat_localMedia); } // Attach the Tracks of the Room's Participants. room.participants.forEach(participant => { console.log('Already in Room: '' + participant.identity + '''); this.setState({ peerIdentity: participant.identity }) var previewContainer = this.refs.remoteMedia; this.attachParticipantTracks(participant, previewContainer); }); // When a Participant joins the Room, log the event. room.on('participantConnected', participant => { console.log('Joining: '' + participant.identity + '''); this.setState({ peerIdentity: participant.identity, partnerConnected: true }) }); // When a Participant adds a Track, attach it to the DOM. room.on('trackAdded', (track, participant) => { console.log(participant.identity + ' added track: ' + track.kind); var previewContainer = this.refs.remoteMedia; this.attachTracks([track], previewContainer); }); // When a Participant removes a Track, detach it from the DOM. room.on('trackRemoved', (track, participant) => { console.log(participant.identity + ' removed track: ' + track.kind); this.detachTracks([track]); }); // When a Participant leaves the Room, detach its Tracks. room.on('participantDisconnected', participant => { console.log('Participant '' + participant.identity + '' left the room'); this.detachParticipantTracks(participant); }); // Once the LocalParticipant leaves the room, detach the Tracks // of all Participants, including that of the LocalParticipant. room.on('disconnected', () => { if (this.state.previewTracks) { this.state.previewTracks.forEach(track => { track.stop(); }); } this.detachParticipantTracks(room.localParticipant); room.participants.forEach(this.detachParticipantTracks); this.state.activeRoom = null; this.setState({ hasJoinedRoom: false, localMediaAvailable: false }); }); } leaveRoom() { this.state.activeRoom.disconnect(); this.setState({ hasJoinedRoom: false, localMediaAvailable: false, peerIdentity: '' }); } render() { /* Hide 'Join Room' button if user has already joined a room */ let joinOrLeaveRoomButton = this.state.hasJoinedRoom ? ( Leave Room ) : ( Join Room ); /** */ return ( {!this.state.hasJoinedRoom && } {this.state.hasJoinedRoom ? Leave Room : } {!this.state.hasParticipantsJoinedRoom && !this.state.peerIdentity && } {(!this.state.hasParticipantsJoinedRoom && !this.state.peerIdentity) ? Wait for peer user to connect channel !!! : Peer User Name : {`${this.state.peerIdentity}`}} ) } } export default App;

Die Twilio-API bietet vordefinierte Funktionen, um mit verschiedenen Benutzern in Verbindung zu treten. Vorausgesetzt, wir erhalten Token, erstellen einen Raum, treten einem Raum bei, verbindenTracks, AttachParticipants, DetachTracks usw. Mit der Verwendung einer vordefinierten Funktion können wir uns mit verschiedenen Benutzern verbinden und jeden Benutzer verfolgen, der verbunden ist oder nicht.

Das ist der Bildtitel

GitHub-Repository

Vielen Dank fürs Lesen!

#reagieren #node-js #twilio