在Ubuntu上部署一個基於webrtc的多人視訊聊天服務
最近研究webrtc視訊直播技術,網上找了些教程最終都不太能順利跑起來的,可能是文章寫的比較老,使用的一些開源元件已經更新了,有些配置已經不太一樣了,所以按照以前的步驟會有問題。折騰了一陣終於跑起來了,記錄一下。
一個簡單的聊天室html頁面
這個頁面使用simple-webrtc來實現webrtc的通訊,simple-webrtc是對幾個webrtc核心物件的封裝,所以使用這個會比較簡單。
<!DOCTYPE html> <html> <head> <title>webrtc chat room </title> <style> video { height: 200px; width: 200px; border: 1px solid cornflowerblue; border-radius: 3px; margin: 10px; } </style> </head> <body> <div> roomid: <input id="roomid" type="text" value=""/> <input type="button" id="btnStart" value="join room"> </div> <div> nick name: <input id ="nickname" readonly="readonly" type = "text" value=""> </div> <h3> self: </h3> <video id="localVideo"></video> <div id="remoteVideos"> <h3> remote clients: </h3> </div> <script src="https://cdn.bootcss.com/jquery/3.3.0/jquery.min.js"></script> <script src="js/simplewebrtc-with-adapter.bundle.js"></script> <script lang="javascript"> $("#nickname").val(new Date().getTime()); var qs = function (key) { return (document.location.search.match(new RegExp("(?:^\\?|&)" + key + "=(.*?)(?=&|$)")) || ['', null])[1]; }; var roomid = qs("roomid"); if (roomid) { $('#roomid').val(roomid); } else { $('#roomid').val('99999'); } // $('#roomid').val(roomid); var smUrl = 'https://webrtc.xxx.com:8800'; var webrtc = new SimpleWebRTC({ // the id/element dom element that will hold "our" video localVideoEl: 'localVideo', // the id/element dom element that will hold remote videos remoteVideosEl: 'remoteVideos', // immediately ask for camera access autoRequestMedia: true, url: smUrl, nick: $('#nickname').val(), }); webrtc.on('readyToCall', function () { // you can name it anything console.log('connectioned .'); }); webrtc.on("createdPeer", function (peer) { console.log('createdPeer', peer, peer.nick ); if (peer.nick) { alert('client '+ peer.nick + ' joined'); } }); webrtc.on("joinedRoom", (roomName )=>{ console.log('joinedRoom', roomName ); alert('joined room ' + roomName ); }); webrtc.on("leftRoom", (roomName )=>{ console.log('leftRoom', roomName ); }); webrtc.on("videoAdded", (videoEl, peer )=>{ console.log('videoAdded', videoEl, peer ); if (peer.nick) { alert('client '+ peer.nick + ' joined'); } }); webrtc.on("videoRemoved", (videoEl, peer )=>{ console.log('videoRemoved', videoEl, peer ); }); $('#btnStart').click(function(){ var roomId = $('#roomid').val(); webrtc.joinRoom(roomId); // alert('join room '+ roomId +' success') }) //$('#btnStart').click(); </script> </body> </html>
安裝nginx並部署聊天室頁面
安裝nginx:
sudo apt-get install nginx
配置nginx:
server { listen 80; listen 443; server_name webrtc.xxx.com; location / { index index.html; root html/www; } ssl on; ssl_certificate /ssl/xxx.crt; ssl_certificate_key /ssl/xxx.key; ssl_session_timeout 5m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; }
安裝完成nginx後把上面的html頁面使用nginx部署到伺服器。注意需要走https,因為chrome的設定不走https沒法呼叫起攝像頭跟麥克風。
安裝並配置signalmaster信令服務
信令服務是用來在客戶端之間傳輸webrtc的客戶端資訊。因為在webrtc建立p2p連線的時候需要對方客戶端的相關資訊,所以需要一個渠道來轉發客戶端之間的資訊。signalmaster是一個基於nodejs的服務,使用socket.io實現websocket長連線。
安裝signalmaster:
git clone https://github.com/simplewebrtc/signalmaster.git
配置signalmaster:
cd signalmaster
cd config
vim development.json
//編輯
{
"isDev": true,
"server": {
"port": 8800,
"/* secure */": "/* whether this connects via https */",
"secure": true,
"cert": "/ssl/xxx.crt",
"key": "/ssl/xxx.key",
"password": null
},
"rooms": {
"/* maxClients */": "/* maximum number of clients per room. 0 = no limit */",
"maxClients": 0
},
"stunservers": [
{
"urls": "stun:webrtc.xxx.com:3478"
}
],
"turnservers": [
{
"urls": ["turn:webrtc.xxx.com:3478"],
"username": "abc",
"credential": "123",
"secret": "",
"expiry": 86400
}
]
}
~
這裡主要注意的是也需要配置ssl證書,證書使用上面nginx那個證書即可。另外trunserver如果設定了密碼也需要配置正確的使用者名稱跟密碼。
安裝並配置coturn穿透服務
我們的客戶端一般都在區域網之內,所以p2p連線建立的時候需要進行內網穿透。使用coturn建立turnserver作為穿透服務。
安裝coturn:
# deps
apt-get install -y \
emacs-nox \
build-essential \
libssl-dev sqlite3 \
libsqlite3-dev \
libevent-dev \
g++ \
libboost-dev \
libevent-dev
# download
wget https://github.com/coturn/coturn/archive/4.5.0.7.tar.gz
tar xvf 4.5.0.7.tar.gz
# build & install
cd coturn-4.5.0.7
./configure --prefix=/opt
make
make install
# env
echo "export PATH=/opt/bin:$PATH" >> ~/.bashrc
source ~/.bashrc
配置coturn:
cd coturn-4.5.0.7
vim coturn.conf
#server
listening-port=3478
listening-ip=
relay-ip=
alt-listening-port=0
external-ip=
realm=abc
# server-name={YOUR_SERVER_NAME}
no-tls
no-dtls
mobility
no-cli
verbose
fingerprint
# auth
lt-cred-mech
stale-nonce=3600
# user
# 這裡是演示,不配置資料庫,通過 use={name}:{password} 方式配置
# userdb=/opt/var/db/turndb
# 多使用者則寫多行
user=abc:123
這裡主要需要注意的是ip的配置listening-ip=內網ip,relay-ip=內網ip,external-ip=外網ip。還有user配置了話,信令伺服器也要配置對應的使用者名稱密碼。
執行所有服務
執行信令服務:
cd signalmaster
node server.js
執行穿透伺服器:
cd coturn-4.5.0.7
turnserver -c coturn.conf
訪問一下nginx部署的靜態頁面就可以啦。開兩個網頁,自己可以跟自己試一下,最好找其他朋友試一下,有的時候穿透服務沒配置好的時候,自己跟自己是可以的,但是跟其他人就不可以了。
參考
Coturn: TURN and STUN Server
5分鐘快速打造WebRTC視訊聊天
Real-time communication for the web
coturn
signalmaster