html5+js+.Net的即時多人聊天

        今天看了下websocket的知識,瞭解到這是html5新增的特性,主要用於實時web的通訊。以前客戶端獲取服務端的數據,是經過客戶端發出請求,服務端進行響應的模式,或者經過ajax每隔一段時間從後臺發出請求,而後更新頁面的信息,這種輪詢的方式使得用戶感受頁面是「實時響應」的,這樣作雖然簡單但未免有些暴力,另外每次請求都會有TCP三次握手而且附帶了http頭信息,服務器表示壓力很大,這就形成了性能上和延遲的問題。html

        後來的技術方案中又出現了長輪詢、Comet、瀏覽器插件(flash)和Java等來實現服務器往客戶端推送消息,但都有一些弊端。html5

        WebSocket的出現,意味着另外一種解決方案,其提供了基於TCP的雙向的、全雙工(發送數據的同時也可以接受數據,二者同步進行)的socket鏈接。使用websocket,一旦服務端和客戶端之間完成握手,信息就能夠隨意往來兩端,而不用附件那些無用的http頭信息,下降了帶寬的佔用,提升了性能,下降了延時。但其缺陷是瀏覽器的支持不夠,好比IE,到了IE10才支持。web

        如今就經過一個簡單的例子來說講其運用過程,先上下效果圖:ajax

即時通信2

         項目的環境:.NET 4.5 +MVC 4 +JQuery+HTML5+VS2013+IE11      chrome

核心的實現過程,分如下幾步:瀏覽器

一、websocket的建立、發送消息、接受消息、關閉服務器

二、服務端的響應websocket

        下面針對上面的步驟,具體講解下:socket

一、websocket的建立、發送消息、接受消息、關閉async

websocket裏包含的幾個重要事件以下圖: onopen onmessage onerror onclose;

image003

           websocket的建立: 這時鏈接會發送到服務端後臺代碼,進行客戶端和服務端的握手,若是握手成功,則會觸發onopen事件,表示鏈接創建;若是鏈接失敗,就會執行onerror事件,隨後執行onclose事件。當客戶端獲取到服務端推送的消息後,就會執行onmessage事件。

    try{
        if ("WebSocket" in window) {   //判斷瀏覽器是否支持WebSocket
            socket = new WebSocket("ws://localhost:13458/Socket/SocketHandler.ashx"); //socket鏈接服務端地址
        }
    }
    catch(ex)
    {
        log("您的瀏覽器不支持WebSocket,請切換到更高版本 或用chrome firefox");
        return;
    }

    //相應的socket事件 
    //socket創建鏈接
    socket.onopen = function () {
        //鏈接成功,將消息廣播出去
        isSocketConnect = true;
        $("#btnWs").val("斷開");
        sendSocketMessage(Event,"進入聊天室");
    }
    //socket獲得服務端廣播的消息
    socket.onmessage = function (event) {
        Log(event.data);
    }
    //socket鏈接關閉
    socket.onclose = function () {
        Log("socket closed!");
    }
    //socket鏈接出現錯誤
    socket.onerror = function (event) {
        Log("socket connect error");
    }
           

          固然客戶端也能夠往服務端發送消息,發送事件即是socket.send(data);data表明發送給服務端的數據:具體代碼以下

if (socket.readyState == WebSocket.OPEN) {
        if ($("#txtMsg").val() == "") {
            if (!msg) {
                return; //空文本不發送消息
            }
        }
        //若是未輸入用戶名,根據當前時間生成遊客暱稱
        if ($("#userName").val() == "") {
            var d = new Date();
            $("#userName").val("遊客" + d.getMinutes() + "_" + d.getSeconds() + "_" + d.getMilliseconds());
        }
        if (!msg) {
            msg = "" + $("#userName").val() + ":" + "<div class='divChat'>" + $("#txtMsg").val() + "</div>";
        }
        else {
            msg = "" + $("#userName").val() + " " + msg;
        }
        socket.send(msg);
        $("#txtMsg").val(""); //清空已輸入的數據
        $("#txtMsg").focus();
    }

        二、服務端的響應

        這裏咱們添加通常處理程序來進行響應和推送客戶端消息,其中有一點要處理的是 咱們要實現即時多人聊天,就要把客戶端發過來的消息廣播到其餘客戶端,這裏實現原理也很簡單,就是把全部的鏈接用list存起來,而後遍歷list集合,將消息發送給各個客戶端。具體實現代碼以下:

    public class SocketHandler : IHttpHandler
    {
        //用來存儲當前全部鏈接的客戶單 
        public static List<WebSocket> WebSocketList;
        public void ProcessRequest(HttpContext context)
        {
            if (WebSocketList == null)
            {
                WebSocketList = new List<WebSocket>();
            }
            HttpContext.Current.AcceptWebSocketRequest(async (contexts) =>
            {
                WebSocket socket = contexts.WebSocket;
                while (true)
                {
                    ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[1024]);
                    CancellationToken token;
                    WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, token);
                    //獲取客戶端發過來的消息
                    string clientMessage = Encoding.UTF8.GetString(buffer.Array, 0, result.Count);

                    if (socket.State == WebSocketState.Open)
                    {
                        //從新組織消息,發送給客戶端
                        clientMessage = DateTime.Now.ToString() + "           " + clientMessage;
                        buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(clientMessage));
                        //若是該客戶端爲初次加入,添加到用戶列表;
                        if (!WebSocketList.Contains(socket))
                        {
                            WebSocketList.Add(socket);
                        }
                        //將消息進行廣播
                        foreach (WebSocket item in WebSocketList)
                        {
                            await item.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
                        }
                    }
                    if (socket.State == WebSocketState.CloseReceived)
                    {
                        //客戶斷開的時候,要從列表中移除
                        WebSocketList.Remove(socket);
                    }
                }
            });
        }

         參考資料:使用 HTML5 WebSocket 構建實時 Web 應用

         源碼下載

         ps:離職了,找工做中……廣州/深圳  圍觀簡歷

         喜歡就動動手指支持下!您的支持是我最大動力!

相關文章
相關標籤/搜索