在網頁里實現文字聊天是比較容易的,但若要實現視頻聊天,就比較麻煩了。這里,我們將實現一個簡單的網頁版視頻聊天Demo,可以支持所有類型的瀏覽器。
本Demo除了視頻聊天功能外,還包含以下功能:
1.上下線通知:假設所有用戶都是好友,任何一個用戶上線,都會出現在其他人的好友列表中,下線則會從好友列表中移除。
2.掉線后會自動進行斷線重連。
3.當同名的用戶登陸時,會把前面的用戶擠掉。
4.所有在線用戶之間進行文字聊天。
5.與在線好友進行視頻聊天。
一. Demo運行效果
先來看看Demo的最終效果吧!文字聊天:
視頻聊天:
二. JS 實現過程
1.實現賬號登錄
登錄界面如下:
打開視頻聊天demo網頁時,會出現登錄界面,輸入視頻服務器IP、賬號(使用隨機生成的就可以),點擊登錄按鈕就可以登錄到視頻聊天服務器。
調用ESFramework框架的RapidPassiveEngine()的initialize方法,以及OMCS框架的MultimediaManager的Initialize方法以完成登錄。
登錄成功后會自動進入用戶主界面。
//OMCS登錄 $('#Singin').bind("click", function () { this.multimediaManager = MultimediaManagerFactory.GetSingleton(); var id = document.getElementById("userID").value;//用戶id var posw = document.getElementById("logonPassword").value;//用戶密碼 var serverIP = document.getElementById("serverIP").value;//ip地址 // var serverPort = document.getElementById("serverPort").value;//端口 try { if (this.multimediaManager.Connected() == true) { this.multimediaManager.Initialize(id, posw, serverIP, 9900); } else { alert("登錄失敗"); console.log("多媒體webSocket還未連成功"); } } catch (ex) { console.log(ex); } }) //ESFramework登錄 $('#Singin').bind("click", function () { engine.initialize({ serverIP: serverIP,//服務器IP serverPort: serverPort,//服務器端口 userID: userID,//登錄用戶名 useWss: false, logonPassword: hex_md5(logonPassword),//md5后的密碼 heartBeat: 5000,//心跳間隔時間(單位為ms) callBackTimeout: 5000,//回調方法超時時間(單位為ms) maxLengthOfUserID: 11,//設置用戶名最大長度 customizeHandler: new CustomizeHandler(),//用戶自定義消息處理器 loginResutCallBack: function (loginResult) {//登錄結果回調方法 if (loginResult.logonResult == 0) {//登錄成功 $("#chatBox").html("登錄服務器成功"); document.getElementById('loginid').innerHTML = '當前賬號 '+userID; document.getElementById('login').style.display = 'none'; document.getElementById('main').style.display = 'block' //esf登錄 engine.ContactsOutter.addEventListener(new contractsListener());//注冊聯系人事件 engine.BasicOutter.addEventListener(new basicListener());//注冊基礎事件 }); };
2. 實現文字聊天
使用通信框架最基礎的需求就是收發信息,ESFramework(WebSocket)底層已經為我們封裝好了所有與信息收發相關的操作, 當RapidPassiveEngine被new出來以后,RapidPassiveEngine對象就實例化了CustomizeOutter 屬性,在對象的initialize函數被調用后,即可調用CustomizeOutter 里面的相關函數來發送消息,以及實現customizeHandler后就可以處理收到的信息。
Web端可以收到來自其它客戶端或服務端的信息、大數據塊、以及同步調用。
(1)發送文字聊天消息
發送文字聊天信息可時通過調用CustomizeOutter中send()來進行操作,再發送前點擊在線用戶即可改變targetUser的值從而綁定你要發送信息的對象。
//選擇聊天對象 function selectUser(userid) { var selfid = document.getElementById('userID').value; targetUser = userid; $("#chatBox").html("正在與" + userid + "對話中....."); var shows = document.getElementById('showfather').children; //console.log(shows); for (var i= 0; i < shows.length; i++) { if (shows[i].id != (userid + 'show')) { shows[i]. className='othershow' } document.getElementById(userid + 'show').className = 'shownow' } }
發送信息時可以自定義不同的參數,從而判斷出不同的消息類型。
//發送信息
$("#btn").bind("click", function () { if ($(".bottomtext").val() == "") { alert("不能發送空消息~"); return; } else if (targetUser.length == 0) { alert("未選中目標用戶~"); return; } else { value = $(".bottomtext").val();
var selfid=document.getElementById('userID').value; appendContent("自己", value,selfid); $(".bottomtext").val(""); var time = []; var info = util.getbytes(value); //以下為與服務端定義的協議體 var stream = new OStream(time); var bodyLen = 4 + 4 + info.length + 4; stream.writeInt32(bodyLen); stream.writeInt32(info.length); stream.write(info); stream.writeInt32(1);//發送時間 距離2016.01.01 00:00:00的總秒數 engine.CustomizeOutter.send(0, stream.getBytesArray(), targetUser); } })
(2)處理文字聊天消息
當我們收到其他在線用戶或者服務端發來的信息時,通過實現customizeHandler接口來獲取和處理信息。
我們在用戶登錄時調用initialize方法時轉入即可自動處理接收到的信息,接收到的信息我們通過判斷信息類型來執行不同的操作。
function CustomizeHandler() { this.handleInformation = function (sourceUserID, informationType, info) { if (informationType == 0)//聊天消息 { } else if (informationType == 1)//視頻消息 { } else if (informationType == 2) { } else if (informationType == 3) { }
(3)渲染顯示文字聊天消息
通過appendOtherContent和appendContent函數將信息在頁面中渲染出來通過傳入的對象OppositeID不同將收到的信息渲染到不同的聊天窗口。並且通過selectUser來切換到發送信息的用戶的窗口。
function appendContent(sendName, content, OppositeID) { Time = getTime(); $("#" + OppositeID).append('<div class="selfstyle"><p class="selfname">' + sendName + ":" + Time + '</p><p>' + content + '</p></div>'); $("#" + OppositeID).animate({ scrollTop: 99999 }); } function appendOtherContent(sendName, content, OppositeID) { Time = getTime(); selectUser(OppositeID); var showid = OppositeID + 'show' $("#" + showid).append('<div class="otherstyle"><p class="othername">' + sendName + ":" + Time + '</p><p>' + content + '</p></div>'); $("#" + showid).animate({ scrollTop: 99999 });
3. 實現視頻聊天
視頻聊天功能可以讓你與服務器上的在線用戶進行視頻聊天,通過OMCS服務插件來實現攝像頭和麥克風的連接,所以在使用前必須打開OMCS視頻服務Web插件才能正常使用。
(1)點擊視頻聊天后先通過CustomizeOutter 的send向對方發送消息類型為1的視頻連接請求數據,同時打開視頻聊天的窗口並且打開自己的攝像頭和麥克風連接
(2)視頻連接對象收到數據類型為1的視頻連接請求后出接受視頻連接的聊天框,可以選擇接受或拒絕.
當視頻連接對象選擇接受視頻聊天,則會同時連接自己和對方的攝像頭麥克風;
當對方拒絕時,則關閉視頻連接的請求。
選擇過后將會發送一條消息類型為2的消息給視頻的發起者。
(3)視頻發起者收到數據為2的回復后,會進行判斷對方的選擇是接受還是拒絕,若是接受則開始連接對方的攝像頭,拒絕則關閉自己的攝像頭麥克風和視頻連接窗口。
(4)當某一方關閉連接或者斷開連接時會發送一條消息類型為3的消息發給另一方,收到類型為3的消息后會斷開自己的攝像頭和麥克風連接。
在連接過程中也可通過視頻聊天窗口的控件,控制自己的攝像頭麥克風的開啟和關閉。
發送視頻請求時間如下(接受拒絕和關閉同理)
$('#videomic').bind('click', function () { if (targetUser.length == 0) { alert("未選中視頻聊天用戶~"); return; } else { value = 'null'; console.log(value); document.getElementById('VideoMic').style.display = 'block'; document.getElementById('VideoHeardTxt').innerHTML = '連接中...'; document.getElementById('VideoSelf').src = 'img/video.jpg' document.getElementById('VideoOther').src = 'img/head.jpg' ConnertVideoSelf(userID, 'VideoSelf') appendContent(selfid, "我發送了視頻請求"); var time = []; var info = util.getbytes(value); //以下為與服務端定義的協議體 var stream = new OStream(time); var bodyLen = 4 + 4 + info.length + 4; stream.writeInt32(bodyLen); stream.writeInt32(info.length); stream.write(info); stream.writeInt32(1);//發送時間 距離2016.01.01 00:00:00的總秒數 var userID = document.getElementById('userID').value; engine.CustomizeOutter.send(1, null, targetUser); } })
視頻麥克風連接事件如下
var microphoneConnector, dynamicCameraConnector; var cameraArr = []; var micArr = []; function Connectvideo(destID, whichimg) { var a = document.getElementById(whichimg); this.dynamicCameraConnector = new DynamicCameraConnector(); this.dynamicCameraConnector.ConnectEnded = connectEnded; //連接成功監聽 this.dynamicCameraConnector.Disconnected = disconnected; //連接關閉監聽 this.dynamicCameraConnector.OwnerOutputChanged = videoOutput; this.dynamicCameraConnector.SetAutoReconnect(true); this.dynamicCameraConnector.AutoReconnectSucceed = videocl; this.dynamicCameraConnector.SetViewer(a); this.dynamicCameraConnector.BeginConnect(destID);//開始攝像頭的連接 cameraArr.push(this.dynamicCameraConnector); this.microphoneConnector = new MicrophoneConnector(); this.microphoneConnector.ConnectEnded = microphone; this.microphoneConnector.OwnerOutputChanged = micOutput; this.microphoneConnector.SetAutoReconnect(true); this.microphoneConnector.AutoReconnectSucceed = miccl; this.microphoneConnector.BeginConnect(destID);//開始麥克風的連接 micArr.push(this.microphoneConnector); }
視頻聊天的幾個特性:
(1)一方發起視頻對話請求,對方同意后,即可開始視頻對話。
(2)在對話的過程中,任何一方都可以掛斷,以終止對話。
(3)在對話的過程中,任何一方掉線,都會自動終止對話。
(4)點擊右下角較小視頻窗口,會放大該視頻顯示窗口。
(5)Web版的視頻聊天可以與pc版視頻聊天互通。
三. 網頁視頻聊天Demo源碼下載
1. 視頻聊天Demo Web端 源碼(JavaScript)
當運行本Demo 的 Web端時,如果尚未安裝OMCS視頻服務Web插件,網頁會自動提示下載安裝。
完成安裝后,刷新網頁,會提示啟動插件,點擊同意啟動后,再次刷新網頁即可進行正常登錄了。Web插件以托盤形式運行,如下圖所示:
如果不想自己編譯服務端和PC客戶端,可以直接下載我們已經編譯好的可直接運行的部署版本: VideoChat.Exe.rar
部署版本壓縮包里的服務端可以放到公網的服務器上,雙擊exe即可運行。PC客戶端修改VideoChat.exe.config配置文件中的IP為公網服務器的IP,即可運行PC客戶端測試。
如此,PC客戶端和Web端即可互通,以進行文字聊天和視頻聊天。
四. 注意事項
1. 首先將服務端部署到服務器上,雙擊exe運行起來,然后再登錄Web端和PC客戶端測試。
2. 一台電腦只能運行一個Demo Web端。
3. 測試視頻聊天時,兩個用戶最好在不同的房間,以防止聲音相互干擾。
4. Web版與在線用戶聊天時,聊天內容並不是保存在雲端的所以用戶下線后記錄會被清空。