1. 程式人生 > >.Net WebSocket學習之旅(一)

.Net WebSocket學習之旅(一)

原生Websocket在.Net環境的實現

使用原生的websocket做了個簡單的demo,適合初學的知道怎麼個實現。

我參考的是網上的,部分雷同,見諒

聊天室功能可以在此基礎上加工,我後面會在SignalR框架中實現

下面是大致的程式碼框架,實現是加上自己的業務的,我會在後面提供我的原始碼,豐富了框架,一個簡單的demo

一、前端Html中的Js

           
           var socket;//建立websocket物件

          $(document).ready(function(){
            //建立連結,開啟連線。使用ws協議,如果報錯注意IIS版本,至少IIS8(我不太確定)
socket = new WebSocket('ws://' + window.location.hostname + ':' + window.location.port + '/App/webSocketHandler.ashx'); socket.onopen = function (event) { //監控websocket開啟的方法 } socket.onclose = function (event) {
            //監控伺服器關閉websocket的方法
//瀏覽器關閉時、url跳轉時,伺服器會接收到當前websocket關閉的通知
}
 socket.onerror = function (event) {
            //監控websocket關閉的方法
}  socket.onmessage = function (event) { //接收到伺服器訊息,具體資訊是json格式,在event的data中。  }
        })
function sendMsg(msg){
           //傳送訊息到伺服器
  if (socket.readyState == WebSocket.OPEN) {
      socket.send(msg);
    }
}

二、前端Html中的html、css,略,看我原始碼

三、後臺處理程式

 public class webSocketHandler : IHttpHandler
   {
      //獲取Dal層的websocket列表,當前每個請求視為一個websocket物件,進來儲存,離開移除。
     public static List<WebSocket> lstWs = WebSocketHelper.lstWs;
    
     public void ProcessRequest(HttpContext context)
      {
         if (context.IsWebSocketRequest)
           {
               context.AcceptWebSocketRequest(ProcessChat);
           }
       }
     
       //一個非同步執行緒
        private async Task ProcessChat(AspNetWebSocketContext context)
        {
            string rspMsg = string.Empty;
            WebSocket socket = context.WebSocket;//獲取當前的websocket物件
            lstWs.Add(socket);//加入當前的websocket物件

            //while不會進入死迴圈
            while (true)
            {
                if (socket.State == WebSocketState.Open)
                {
                    ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[2048]);
                    WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, CancellationToken.None);
                    
                    //當接收到瀏覽器關閉、url跳轉、報錯等問題,伺服器會接收到websocket關閉通知
                    if (result.MessageType == WebSocketMessageType.Close)
                    {   
                        //非同步關閉websocket連線
                        await socket.CloseAsync(WebSocketCloseStatus.Empty, string.Empty, CancellationToken.None);
                        lstWs.Remove(socket);
                        break;
                    }

                    //這裡打斷點除錯,你會發現while程式不會死迴圈,直到下面的方法收到資訊,或者上面接收到關閉
                    string userMsg = Encoding.UTF8.GetString(buffer.Array, 0, result.Count);
                    rspMsg = DateTime.Now.ToLongTimeString() + "  你傳送了:" + userMsg;

                    buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(rspMsg));
                   //傳送到當前使用者的客戶端
                    await socket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
                }
                else
                {
                    break;
                }
            }
        }

   //DAL層的程式
  public class WebSocketHelper
  {
    public static List<WebSocket> lstWs = new List<WebSocket>();

     /// <summary>
     /// 封裝推送訊息,然後傳送給每位線上的
     /// </summary>
     /// <param name="json">json格式推送內容</param>
    public void Push2EveryOne(string json = "")
    {
     //封裝推送訊息,然後傳送給每位線上的
     ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[2048]);
     buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(json));

     foreach (WebSocket socket in lstWs)
     {
       socket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
     }
    }
  }


我做了個簡單的demo,看下截圖,裡面稍微豐富了下,有興趣下載原始碼(MVC4.5)