WebRTC - Invio di messaggi

Ora creiamo un semplice esempio. In primo luogo, eseguire il server di segnalazione che abbiamo creato nel tutorial "server di segnalazione" tramite "server nodo".

Ci saranno tre input di testo nella pagina, uno per un login, uno per un nome utente e uno per il messaggio che vogliamo inviare all'altro peer. Crea un file index.html e aggiungi il seguente codice:

<html lang = "en"> 
   <head> 
      <meta charset = "utf-8" /> 
   </head>
	
   <body> 
      <div> 
         <input type = "text" id = "loginInput" /> 
         <button id = "loginBtn">Login</button> 
      </div> 
		
      <div> 
         <input type = "text" id = "otherUsernameInput" /> 
         <button id = "connectToOtherUsernameBtn">Establish connection</button> 
      </div> 
		
      <div> 
         <input type = "text" id = "msgInput" /> 
         <button id = "sendMsgBtn">Send text message</button> 
      </div> 
		
      <script src = "client.js"></script>
   </body>
	
</html>

Abbiamo anche aggiunto tre pulsanti per accedere, stabilire una connessione e inviare un messaggio. Ora crea un file client.js e aggiungi il seguente codice:

var connection = new WebSocket('ws://localhost:9090'); 
var name = "";

var loginInput = document.querySelector('#loginInput'); 
var loginBtn = document.querySelector('#loginBtn'); 

var otherUsernameInput = document.querySelector('#otherUsernameInput'); 
var connectToOtherUsernameBtn = document.querySelector('#connectToOtherUsernameBtn'); 
var msgInput = document.querySelector('#msgInput'); 
var sendMsgBtn = document.querySelector('#sendMsgBtn'); 
var connectedUser, myConnection, dataChannel;
  
//when a user clicks the login button 
loginBtn.addEventListener("click", function(event) { 
   name = loginInput.value; 
	
   if(name.length > 0) { 
      send({ 
         type: "login", 
         name: name 
      }); 
   } 
}); 
 
//handle messages from the server 
connection.onmessage = function (message) { 
   console.log("Got message", message.data); 
   var data = JSON.parse(message.data); 
	
   switch(data.type) { 
      case "login": 
         onLogin(data.success); 
         break; 
      case "offer": 
         onOffer(data.offer, data.name); 
         break; 
      case "answer":
         onAnswer(data.answer); 
         break; 
      case "candidate": 
         onCandidate(data.candidate); 
         break; 
      default: 
         break; 
   } 
}; 
 
//when a user logs in 
function onLogin(success) { 

   if (success === false) { 
      alert("oops...try a different username"); 
   } else { 
      //creating our RTCPeerConnection object 
      var configuration = { 
         "iceServers": [{ "url": "stun:stun.1.google.com:19302" }] 
      }; 
		
      myConnection = new webkitRTCPeerConnection(configuration, { 
         optional: [{RtpDataChannels: true}] 
      }); 
		
      console.log("RTCPeerConnection object was created"); 
      console.log(myConnection); 
  
      //setup ice handling 
      //when the browser finds an ice candidate we send it to another peer 
      myConnection.onicecandidate = function (event) { 
		
         if (event.candidate) { 
            send({ 
               type: "candidate", 
               candidate: event.candidate 
            });
         } 
      }; 
		
      openDataChannel();
		
   } 
};
  
connection.onopen = function () { 
   console.log("Connected"); 
}; 
 
connection.onerror = function (err) { 
   console.log("Got error", err); 
};
  
// Alias for sending messages in JSON format 
function send(message) { 
   if (connectedUser) { 
      message.name = connectedUser; 
   }
	
   connection.send(JSON.stringify(message)); 
};

Puoi vedere che stabiliamo una connessione socket al nostro server di segnalazione. Quando un utente fa clic sul pulsante di accesso, l'applicazione invia il suo nome utente al server. Se il login ha esito positivo, l'applicazione crea l' oggetto RTCPeerConnection e configura il gestore onicecandidate che invia tutti i icecandidate trovati all'altro peer. Esegue anche la funzione openDataChannel () che crea un dataChannel. Si noti che durante la creazione dell'oggetto RTCPeerConnection il secondo argomento nel costruttore opzionale: [{RtpDataChannels: true}] è obbligatorio se si utilizza Chrome o Opera. Il passaggio successivo consiste nel creare un'offerta per l'altro peer. Aggiungi il seguente codice al tuo file client.js -

//setup a peer connection with another user 
connectToOtherUsernameBtn.addEventListener("click", function () {
  
   var otherUsername = otherUsernameInput.value;
   connectedUser = otherUsername;
	
   if (otherUsername.length > 0) { 
      //make an offer 
      myConnection.createOffer(function (offer) { 
         console.log(); 
			
         send({ 
            type: "offer", 
            offer: offer 
         }); 
			
         myConnection.setLocalDescription(offer); 
      }, function (error) { 
         alert("An error has occurred."); 
      }); 
   } 
});
  
//when somebody wants to call us 
function onOffer(offer, name) { 
   connectedUser = name; 
   myConnection.setRemoteDescription(new RTCSessionDescription(offer));
	
   myConnection.createAnswer(function (answer) { 
      myConnection.setLocalDescription(answer); 
		
      send({ 
         type: "answer", 
         answer: answer 
      }); 
		
   }, function (error) { 
      alert("oops...error"); 
   }); 
}

//when another user answers to our offer 
function onAnswer(answer) { 
   myConnection.setRemoteDescription(new RTCSessionDescription(answer)); 
}
  
//when we got ice candidate from another user 
function onCandidate(candidate) { 
   myConnection.addIceCandidate(new RTCIceCandidate(candidate)); 
}

Puoi vedere che quando un utente fa clic sul pulsante "Stabilisci connessione", l'applicazione fa un'offerta SDP all'altro peer. Abbiamo anche impostato i gestori onAnswer e onCandidate . Infine, implementiamo la funzione openDataChannel () che crea il nostro dataChannel. Aggiungi il seguente codice al tuo file client.js -

//creating data channel 
function openDataChannel() { 

   var dataChannelOptions = { 
      reliable:true 
   }; 
	
   dataChannel = myConnection.createDataChannel("myDataChannel", dataChannelOptions);
	
   dataChannel.onerror = function (error) { 
      console.log("Error:", error); 
   };
	
   dataChannel.onmessage = function (event) { 
      console.log("Got message:", event.data); 
   };  
}
  
//when a user clicks the send message button 
sendMsgBtn.addEventListener("click", function (event) { 
   console.log("send message");
   var val = msgInput.value; 
   dataChannel.send(val); 
});

Qui creiamo il dataChannel per la nostra connessione e aggiungiamo il gestore di eventi per il pulsante "invia messaggio". Ora apri questa pagina in due schede, accedi con due utenti, stabilisci una connessione e prova a inviare messaggi. Dovresti vederli nell'output della console. Si noti che l'esempio sopra è stato testato in Opera.

Ora potresti vedere che RTCDataChannel è una parte estremamente potente dell'API WebRTC. Esistono molti altri casi d'uso per questo oggetto, come i giochi peer-to-peer o la condivisione di file basata su torrent.