WebRTC - Senden von Nachrichten
Lassen Sie uns nun ein einfaches Beispiel erstellen. Führen Sie zunächst den im Tutorial "Signalisierungsserver" erstellten Signalisierungsserver über "Knotenserver" aus.
Auf der Seite befinden sich drei Texteingaben, eine für ein Login, eine für einen Benutzernamen und eine für die Nachricht, die wir an den anderen Peer senden möchten. Erstellen Sie eine index.html- Datei und fügen Sie den folgenden Code hinzu:
<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>
Wir haben außerdem drei Schaltflächen zum Anmelden, Herstellen einer Verbindung und Senden einer Nachricht hinzugefügt. Erstellen Sie nun eine client.js- Datei und fügen Sie den folgenden Code hinzu:
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));
};
Sie sehen, dass wir eine Socket-Verbindung zu unserem Signalisierungsserver herstellen. Wenn ein Benutzer auf die Anmeldeschaltfläche klickt, sendet die Anwendung seinen Benutzernamen an den Server. Wenn die Anmeldung erfolgreich ist, erstellt die Anwendung das RTCPeerConnection- Objekt und richtet einen Kandidaten- Handler ein, der alle gefundenen Eiskandidaten an den anderen Peer sendet. Außerdem wird die Funktion openDataChannel () ausgeführt, mit der ein Datenkanal erstellt wird. Beachten Sie, dass beim Erstellen des RTCPeerConnection-Objekts das zweite Argument im optionalen Konstruktor optional ist: [{RtpDataChannels: true}], wenn Sie Chrome oder Opera verwenden. Der nächste Schritt besteht darin, ein Angebot für den anderen Peer zu erstellen. Fügen Sie Ihrer client.js- Datei den folgenden Code hinzu
//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));
}
Sie können sehen, dass die Anwendung, wenn ein Benutzer auf die Schaltfläche "Verbindung herstellen" klickt, dem anderen Peer ein SDP-Angebot macht. Wir setzen auch onAnswer- und onCandidate- Handler. Lassen Sie uns abschließend die Funktion openDataChannel () implementieren, mit der unser Datenkanal erstellt wird. Fügen Sie der Datei client.js den folgenden Code hinzu :
//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);
});
Hier erstellen wir den Datenkanal für unsere Verbindung und fügen den Ereignishandler für die Schaltfläche "Nachricht senden" hinzu. Öffnen Sie nun diese Seite auf zwei Registerkarten, melden Sie sich mit zwei Benutzern an, stellen Sie eine Verbindung her und versuchen Sie, Nachrichten zu senden. Sie sollten sie in der Konsolenausgabe sehen. Beachten Sie, dass das obige Beispiel in Opera getestet wurde.
Jetzt können Sie sehen, dass RTCDataChannel ein äußerst leistungsfähiger Bestandteil der WebRTC-API ist. Es gibt viele andere Anwendungsfälle für dieses Objekt, wie Peer-to-Peer-Spiele oder Torrent-basierte Dateifreigabe.