在網頁裡實現文字聊天是比較容易的,但若要實現視訊聊天,就比較麻煩了。這裡,我們將實現一個簡單的網頁版視訊聊天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)

2. 視訊聊天Demo 服務端+PC端 原始碼

當執行本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版與線上使用者聊天時,聊天內容並不是儲存在雲端的所以使用者下線後記錄會被清空。

若測試過程中遇到任何問題,可以聯絡QQ:1500207630