當收到otherjoin的時候,狀态變成joined_conn,變成這種狀态之後我們就可以做媒體協商了,
socket.on('otherjoin', (roomid) => {
console.log('receive joined message:', roomid, state);
state = 'joined_conn';
});
這時候還有一個問題,就是說我們有兩個使用者,這時候已經通訊完了,其中主叫方已經離開了,那這個時候留在這個房間裡的使用者,它變成了joined_unbind,就是未綁定狀态,那對于未綁定狀态,這時候又有一個使用者進入進來的時候那它會變成什麼呢?他也會變成這個joined_conn狀态,但是也要重新做一下createConnnection,因為在上一個使用者離開的時候已經把相應的PeerConnection給銷毀掉了,是以現在要重建立一個,那這時候我們要做一個判斷,也就是如果這個時候的狀态是joined_unbind,它要做的就是createPeerConnection也就是創立一個連接配接并進行綁定,這樣我們添加消息和另外一個使用者 加入的消息我們就處理完了。這時候我們把這個狀态列印一下:
socket.on('joined', (roomid, id) => {
console.log('receive joined message!', roomid, id);
state = 'joined'
//如果是多人的話,第一個人不該在這裡建立peerConnection
//都等到收到一個otherjoin時再建立
//是以,在這個消息裡應該帶目前房間的使用者數
//
//create conn and bind media track
createPeerConnection();
bindTracks();
btnConn.disabled = true;
btnLeave.disabled = false;
console.log('receive joined message, state=', state);
});
socket.on('otherjoin', (roomid) => {
console.log('receive joined message:', roomid, state);
if(state === 'joined_unbind'){
createPeerConnection();
}
state = 'joined_conn';
// 媒體協商
console.log('receive other_join message, state=', state);
});
在下來就是房間滿了,我之間設定一下狀态就行了,我們不能讓他在這,也就是收到full的狀态的時候 ,實際狀态已經變成leaved了,這個時候我們要将這個連接配接斷掉,否則的話它雖然沒加入到房間,但是與服務端連接配接還在。這時候我們把它這個連接配接給關了。
socket.on('full', (roomid, id) => {
console.log('receive full message', roomid, id);
state = 'leaved';
console.log('receive full message, state=', state);
socket.disconnect(); // 這個時候我們要将這個連接配接斷掉
alert('the room is full!');
});
在下一個就是leaved,對于leaved來說其實就是在我們主動調leave的時候已經做了一些邏輯,收到leave之後就關閉這個連接配接 就好了其實不用做太多的事情, 和上面的full其實是一樣的,
socket.on('leaved', (roomid, id) => {
console.log('receive leaved message', roomid, id);
state='leaved'
socket.disconnect(); // 關閉連接配接
console.log('receive leaved message, state=', state);
btnConn.disabled = false;
btnLeave.disabled = true;
});
最後一個是當我們收到對端走開的時候,那這個時候要把狀态變成joined_unbind,無論你以前是join_conn還是joined狀态,這時候當有一個使用者走的時候,我們這時候都變成了未綁定的狀态,
socket.on('bye', (room, id) => {
console.log('receive bye message', roomid, id);
state = 'joined_unbind';
createPeerConnection();
console.log('receive bye message, state=', state);
});
這個就是收到了伺服器發來的消息,我們做了相應的處理,一共是5個。
那接下來就是端對端的消息;那當我們收到端對端的消息會怎麼樣,那實際收到端對端的消息實際主要就是媒體協商這塊的,,但是對于這個消息我們還是可以寫一個發送媒體協商的消息,媒體協商這塊我們下次再介紹。
socket.on('message', (roomid, data) => {
console.log('receive client message:', roomid, data);
});
那這樣我們基本上就将整個邏輯基本上寫完了 ,這裡還有一個leave,當leave的時候我們發送了一個leave消息,然後将這個對應的值給設好了,但實際當我們真正離開的時候,我們還是要關閉我們相應的資源的,這個資源就包括了我們現在使用的PeerConnection以及我們開啟的這個音視訊裝置,是以這塊我們要準備一個釋放資源的。
我們要将連接配接和自己的媒體的裝置關閉 ,關閉媒體裝置實際就是關閉它的track.
function leave() {
if(socket){
socket.emit('leave', roomid); //notify server
}
closePeerConnection(); // 将連接配接關閉
closeLocalMedia(); // 關閉媒體的裝置
btnConn.disabled = false;
btnLeave.disabled = true;
}
function closeLocalMedia(){
if(localStream && localStream.getTracks()){
localStream.getTracks().forEach((track)=>{
track.stop();
});
}
localStream = null;
}
那麼我們整個連接配接PeerConnection這塊就完成了;
也就是說這節我們首先實作了如何去建立一個 PeerConnection,PeerConnection有一個參數pcConfig,pcConfig實際有好幾個參數,最主要的是這個iceServers,在這個 iceServer裡我們配了一個TURN 服務 ,有使用者名密碼,當我們建立了這個連接配接之後就将這個連接配接設定進去了,在PeerConnection裡我們要監聽兩個事件,第一個是onicecandidate,當我們後面做協商的時候,這個onicecandidate就會被收集到,當我們收集到的時候,這裡需要發送給對端做端對端的消息傳輸,這裡我們沒有做 ,我們先打個日志,這樣就發現了對應的candidate,但是這時候肯定 不會觸發了,因為我們沒有做媒體協商,也沒有做setLocalDesciption,是以這塊肯定不會觸發;
另外一個就是當我們建立這個資料連接配接之後,它會有遠端的資料過來觸發這個ontrack事件,當收到ontrack這個事件之後我們會擷取其中的一個流,然後我們将它設定到遠端的remoteVideo上去,這樣就可以顯示遠端的資料了,那在這裡我們也可以看到,在PeerConnection裡面我們可以同時傳多路流過來,建立完這個peerconnection之後我們又将本地擷取的localStream,然後從它這裡擷取了對應的音頻和視訊這些Track,與這個PeerConnection進行了一次綁定,也就是把它添加到這個PeerConnection裡面,對這個就是getMediaStream擷取到的,這是建立連接配接。