- WebRTC 教程
- WebRTC - 首頁
- WebRTC - 概覽
- WebRTC - 架構
- WebRTC - 環境
- WebRTC - MediaStream APIs
- WebRTC - RTCPeerConnection APIs
- WebRTC - RTCDataChannel APIs
- WebRTC - 傳送訊息
- WebRTC - 信令
- WebRTC - 瀏覽器支援
- WebRTC - 移動裝置支援
- WebRTC - 影片演示
- WebRTC - 語音演示
- WebRTC - 文字演示
- WebRTC - 安全性
- WebRTC 資源
- WebRTC - 快速指南
- WebRTC - 有用資源
- WebRTC - 討論
WebRTC - 傳送訊息
現在讓我們建立一個簡單的例子。首先,透過“node server”執行我們在“信令伺服器”教程中建立的信令伺服器。
頁面上將有三個文字輸入框,一個用於登入,一個用於使用者名稱,一個用於我們想要傳送給另一個對等節點的訊息。建立一個index.html檔案並新增以下程式碼 -
<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>
我們還添加了三個按鈕,用於登入、建立連線和傳送訊息。現在建立一個client.js檔案並新增以下程式碼 -
var connection = new WebSocket('ws://: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));
};
您可以看到我們建立了一個到信令伺服器的套接字連線。當用戶點選登入按鈕時,應用程式將其使用者名稱傳送到伺服器。如果登入成功,應用程式將建立RTCPeerConnection物件並設定onicecandidate處理程式,該處理程式將所有找到的 icecandidates 傳送到另一個對等節點。它還執行openDataChannel()函式,該函式建立一個dataChannel。請注意,在建立RTCPeerConnection物件時,建構函式中的第二個引數是可選的:[{RtpDataChannels: true}],如果您使用的是Chrome或Opera,則此引數是必需的。下一步是向另一個對等節點發出一個Offer。將以下程式碼新增到您的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));
}
您可以看到,當用戶點選“建立連線”按鈕時,應用程式會向另一個對等節點發出一個SDP Offer。我們還設定了onAnswer和onCandidate處理程式。最後,讓我們實現openDataChannel()函式,該函式建立我們的dataChannel。將以下程式碼新增到您的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);
});
在這裡,我們為我們的連線建立了dataChannel,併為“傳送訊息”按鈕添加了事件處理程式。現在在兩個標籤頁中開啟此頁面,使用兩個使用者登入,建立連線,並嘗試傳送訊息。您應該在控制檯輸出中看到它們。請注意,以上示例在Opera中進行了測試。
現在您可能會發現RTCDataChannel是WebRTC API中極其強大的部分。此物件還有許多其他用例,例如點對點遊戲或基於 torrent 的檔案共享。