<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      史上最全面的SignalR系列教程-6、SignalR 實現聊天室

      1、概述

      通過前面幾篇文章對SignalR的詳細介紹。我們知道Asp.net SignalR是微軟為實現實時通信的一個類庫。一般情況下,SignalR會使用JavaScript的長輪詢(long polling)的方式來實現客戶端和服務器通信,隨著Html5中WebSockets出現,SignalR也支持WebSockets通信。另外SignalR開發的程序不僅僅限制于宿主在IIS中,也可以宿主在任何應用程序,包括控制臺,客戶端程序和Windows服務等,另外還支持Mono,這意味著它可以實現跨平臺部署在Linux環境下。

      SignalR內部有兩類對象:

      1. Http持久連接(Persisten Connection)對象:用來解決長時間連接的功能。還可以由客戶端主動向服務器要求數據,而服務器端不需要實現太多細節,只需要處理PersistentConnection 內所提供的五個事件:OnConnected, OnReconnected, OnReceived, OnError 和 OnDisconnect 即可。

      2. Hub(集線器)對象:用來解決實時(realtime)信息交換的功能,服務端可以利用URL來注冊一個或多個Hub,只要連接到這個Hub,就能與所有的客戶端共享發送到服務器上的信息,同時服務端可以調用客戶端的腳本。

      SignalR將整個信息的交換封裝起來,客戶端和服務器都是使用JSON來溝通的,在服務端聲明的所有Hub信息,都會生成JavaScript輸出到客戶端,.NET則依賴Proxy來生成代理對象,而Proxy的內部則是將JSON轉換成對象。

      2、SignalR實現聊天室(群聊)功能

      要想實現群聊的功能,首先我們需要創建一個房間,然后每個在線用戶可以加入這個房間里面進行群聊,我們可以為房間設置一個唯一的名字來作為標識。那SignalR類庫里面是否有這樣現有的方法呢?答案是肯定的。SignalR作為一個強大的集線器,已經在hub里面集成了Gorups,也就是分組管理。

      // IGroupManager接口提供如下方法 
      // 作用:將連接ID加入某個組 
      // Context.ConnectionId 連接ID,每個頁面連接集線器即會產生唯一ID 
      // roomName分組的名稱 
      Groups.Add(Context.ConnectionId, roomName); 
       
      // 作用:將連接ID從某個分組移除 
      Groups.Remove(Context.ConnectionId, roomName); 
       
      // IHubConnectionContext接口提供了如下方法 
      // 調用客戶端方法向房間內所有用戶群發消息  
      // Room:分組名稱 
      // new string[0]:過濾(不發送)的連接ID數組 
      Clients.Group(Room, new string[0]).clientMethod
      

      上面的代碼就是實現群聊的核心方法。Groups對象就是SignalR類庫維護的一個列表對象而已,我們完全可以自己維護一個Dictionary<string, List>對象,創建一個房間的時候,我們將房間名稱和進入房間的客戶端的ConnectionId加入到這個字典里面,然后在聊天室里面點發送消息的時候,我們根據房間名查找到所有加入群聊的ConnectionId,然后調用Clients.Clients(IList connectionIds)方法來將消息群發到每個客戶端。以上也就是實現聊天室的原理。

      2.1、 創建ASP.NET Mvc項目

      新建一個空的ASP.NET Mvc項目,取名為:SignalRGroupChat。

      2.2、安裝Nuget包

      創建好項目后,要使用SignalR,需要先安裝SignalR包,可以通過程序包管理控制臺輸入包安裝命令進行安裝。

      Install-Package Microsoft.AspNet.SignalR
      Install-Package Microsoft.Owin.Cors
      

      2.3、聊天室后臺代碼實現

      要實現聊天室功能,我們需要一些基礎實體,如:用戶類、房間類等,直接上代碼:

      using System.Collections.Generic;
      using System.ComponentModel.DataAnnotations;
      
      namespace SignalRGroupChat
      {
          public class UserContext
          {
              public UserContext()
              {
                  Users = new List<User>();
                  Connections = new List<Connection>();
                  Rooms = new List<ConversationRoom>();
              }
      
              /// <summary>
              /// 用戶集合
              /// </summary>
              public List<User> Users { get; set; }
      
              /// <summary>
              /// 連接集合
              /// </summary>
              public List<Connection> Connections { get; set; }
      
              /// <summary>
              /// 房間集合
              /// </summary>
              public List<ConversationRoom> Rooms { get; set; }
          }
      
          public class User
          {
              /// <summary>
              /// 用戶名
              /// </summary>
              [Key]        
              public string UserName { get; set; }
      
              /// <summary>
              /// 用戶的連接
              /// </summary>
              public List<Connection> Connections { get; set; }
      
              /// <summary>
              /// 用戶房間集合
              /// </summary>
              public virtual List<ConversationRoom> Rooms { get; set; }
      
              public User()
              {
                  Connections = new List<Connection>();
                  Rooms = new List<ConversationRoom>();
              }
          }
      
          public class Connection
          {
              /// <summary>
              /// 連接ID
              /// </summary>
              public string ConnectionID { get; set; }
      
              /// <summary>
              /// 用戶代理
              /// </summary>
              public string UserAgent { get; set; }
      
              /// <summary>
              /// 是否連接
              /// </summary>
              public bool Connected { get; set; }
          }
      
          /// <summary>
          /// 房間類
          /// </summary>
          public class ConversationRoom
          {
              /// <summary>
              /// 房間名稱
              /// </summary>
              [Key]
              public string RoomName { get; set; }
      
              /// <summary>
              /// 用戶集合
              /// </summary>
              public virtual List<User> Users { get; set; }
      
              public ConversationRoom()
              {
                  Users = new List<User>();
              }
          }
      }
      

      實現聊天室的SignalR Hub代碼:

      using Microsoft.AspNet.SignalR;
      using Microsoft.AspNet.SignalR.Hubs;
      using Newtonsoft.Json;
      using System;
      using System.Linq;
      using System.Threading.Tasks;
      
      namespace SignalRGroupChat.Hubs
      {
          /// <summary>
          /// 聊天室(群聊)
          /// </summary>
          [HubName("groupHub")]
          public class GroupHub : Hub
          {
              public static UserContext db = new UserContext();
              public void Hello()
              {
                  Clients.All.hello();
              }
      
              /// <summary>
              /// 重寫Hub連接事件
              /// </summary>
              /// <returns></returns>
              public override Task OnConnected()
              {
                  // 查詢用戶。
                  var user = db.Users.SingleOrDefault(u => u.UserName == Context.ConnectionId);
      
                  //判斷用戶是否存在,否則添加
                  if (user == null)
                  {
                      user = new User()
                      {
                          UserName = Context.ConnectionId
                      };
                      db.Users.Add(user);
                  }
                  //發送房間列表
                  var itme = from a in db.Rooms
                             select new { a.RoomName };
                  Clients.Client(this.Context.ConnectionId).getRoomlist(JsonConvert.SerializeObject(itme.ToList()));
                  return base.OnConnected();
              }
      
              /// <summary>
              /// 更新所有用戶的房間列表
              /// </summary>
              private void GetRoomList()
              {
                  var itme = from a in db.Rooms
                             select new { a.RoomName };
                  string jsondata = JsonConvert.SerializeObject(itme.ToList());
                  Clients.All.getRoomlist(jsondata);
              }
      
              // 重寫Hub連接斷開的事件 
              public override Task OnDisconnected(bool stopCalled)
              {
                  // 查詢用戶 
                  var user = db.Users.FirstOrDefault(u => u.UserName == Context.ConnectionId);
                  if (user != null)
                  {
                      // 刪除用戶 
                      db.Users.Remove(user);
                      // 從房間中移除用戶 
                      foreach (var item in user.Rooms)
                      {
                          RemoveFromRoom(item.RoomName);
                      }
                  }
                  return base.OnDisconnected(stopCalled);
              }
      
              /// <summary>
              /// 加入聊天室
              /// </summary>
              /// <param name="roomName"></param>
              public void AddToRoom(string roomName)
              {
                  //查詢聊天室
                  var room = db.Rooms.Find(a => a.RoomName == roomName);
                  //存在則加入
                  if (room != null)
                  {
                      //查找房間中是否存在此用戶
                      var isuser = room.Users.Where(a => a.UserName == Context.ConnectionId).FirstOrDefault();
                      //不存在則加入
                      if (isuser == null)
                      {
                          var user = db.Users.Find(a => a.UserName == Context.ConnectionId);
                          user.Rooms.Add(room);
                          room.Users.Add(user);
                          Groups.Add(Context.ConnectionId, roomName);
                          //調用此連接用戶的本地JS(顯示房間)
                          Clients.Client(Context.ConnectionId).addRoom(roomName);                   
                      }
                      else
                      {
                          Clients.Client(Context.ConnectionId).showMessage("請勿重復加入房間!");
                      }
                  }
              }
      
              /// <summary>
              /// 創建聊天室
              /// </summary>
              /// <param name="roomName"></param>
              public void CreatRoom(string roomName)
              {
                  var room = db.Rooms.Find(a => a.RoomName == roomName);
                  if (room == null)
                  {
                      ConversationRoom cr = new ConversationRoom()
                      {
                          RoomName = roomName
                      };
                      //將房間加入列表
                      db.Rooms.Add(cr);
                      AddToRoom(roomName);
                      Clients.Client(Context.ConnectionId).showMessage("房間創建完成!");
                      GetRoomList();
                  }
                  else
                  {
                      Clients.Client(Context.ConnectionId).showMessage("房間名重復!");
                  }
              }
      
              /// <summary>
              /// 退出聊天室
              /// </summary>
              /// <param name="roomName"></param>
              public void RemoveFromRoom(string roomName)
              {
      
                  //查找房間是否存在
                  var room = db.Rooms.Find(a => a.RoomName == roomName);
                  //存在則進入刪除
                  if (room != null)
                  {
                      //查找要刪除的用戶
                      var user = room.Users.Where(a => a.UserName == Context.ConnectionId).FirstOrDefault();
                      //移除此用戶
                      room.Users.Remove(user);
                      //如果房間人數為0,則刪除房間
                      if (room.Users.Count <= 0)
                      {
                          db.Rooms.Remove(room);
      
                      }
                      Groups.Remove(Context.ConnectionId, roomName);
                      //提示客戶端
                      Clients.Client(Context.ConnectionId).removeRoom("退出成功!");
                  }
              }
      
              /// <summary>
              /// 給分組內所有的用戶發送消息
              /// </summary>
              /// <param name="Room">分組名</param>
              /// <param name="Message">信息</param>
              public void SendMessage(string Room, string Message)
              {
                  Clients.Group(Room, new string[0]).sendMessage(Room, Message + " " + DateTime.Now.ToString("HH:mm:ss"));
              }
          }
      }
      

      2.4、頁面部分代碼參考

      @{
          ViewBag.Title = "GroupChat";
      }
      
      <h2>聊天室(群聊)實例</h2>
      <div class="row">
          當前用戶:<label id="username"></label> 
      </div>
      <div class="row">
          輸入房間名:<input type="text" class="form-control" style="display: initial;" value="技術交流1" id="Roomname" /><button id="CreatRoom" class="btn btn-success">創建聊天室</button>     
      </div>
      <div class="row">
          <div class="col-md-3">
              <div style="float:left;border:1px solid #ff0000;margin:5px;">
                  <div>房間列表</div>               
                  <ul id="roomlist">
                  </ul>
              </div> 
          </div>
          <div class="col-md-9">
               <div id="RoomList">
          </div>
          </div>  
      </div>
      <div class="row">
          <div class="col-md-4"></div>
          <ul id="UserList"></ul>
          <div class="col-md-8"></div>  
      </div>
      
      <br />
      
      @section scripts {
          <script src="~/Scripts/jquery-3.3.1.min.js"></script>
          <script src="~/Scripts/jquery.signalR-2.4.1.min.js"></script>
          <script src="~/signalr/hubs"></script>
          <script type="text/javascript">
              var chat
              var roomcount = 0;
              $(function () {
                  chat = $.connection.groupHub;
                  chat.client.showMessage = function (Message) {
                      alert(Message);
                  }
      
                  chat.client.sendMessage = function (roomname, message) {
                      $("#" + roomname).find("ul").each(function () {
                          $(this).append('<li>'+message+'</li>')
                      })
                  }
                  chat.client.removeRoom = function (data) {
                      alert(data);
                  }
                  chat.client.addRoom = function (roomname) {
                      var html = '<table class="table"><tr><td><div style="width: 80%;margin:5px;border:1px solid #ff0000;" id="' + roomname + '" roomname="' + roomname + '"><button onclick="RemoveRoom(this)"  class="btn-danger">退出</button>\
                                      <label>' + roomname + '</label>房間\
                                                  聊天記錄如下:<ul>\
                                                  </ul>\
                                      <input type="text" /> <button class="btn btn-success" onclick="SendMessage(this)">發送</button>\
                                      </div></td></tr></table>'
                      $("#RoomList").append(html);
                  }
      
                  //注冊查詢房間列表的方法
                  chat.client.getRoomlist = function (data) {
                      if (data) {
                          var jsondata = $.parseJSON(data);
                          $("#roomlist").html(" ");
                          for (var i = 0; i < jsondata.length; i++) {
                              var html = ' <li>房間名:' + jsondata[i].RoomName + '<button roomname="'+jsondata[i].RoomName+'"  class="btn-sm btn-info" onclick="AddRoom(this)">加入</button></li>';
                              $("#roomlist").append(html);
                          }
                      }
                  }
      
                  // 獲取用戶名稱。
                  $('#username').html(prompt('請輸入您的名稱:', ''));
      
                  $.connection.hub.start().done(function () {
                      $('#CreatRoom').click(function () {
                          if (roomcount < 2) {
                              chat.server.creatRoom($("#Roomname").val());
                              roomcount++;
                          } else {
                              alert("聊天窗口只允許有2個")
                          }
                      })
                  });
              });
      
              function SendMessage(btn) {
                  var message = $(btn).prev().val();
                  var room = $(btn).parent();
                  var username = $("#username").html();
                  message = username + ":" + message;
                  var roomname = $(room).attr("roomname");
                  chat.server.sendMessage(roomname,message);
              }
      
              function RemoveRoom(btn) {
                  var room = $(btn).parent();
                  var roomname = $(room).attr("roomname");
                  $(room).remove();
                  chat.server.removeFromRoom(roomname);
              }
      
              function AddRoom(roomname) {
                   var data =$(roomname).attr("roomname");
                   chat.server.addToRoom(data);
              }
          </script>
      }
      

      3、效果展示

      效果展示

      4、代碼下載

      實例源碼可以移步github下載,地址:https://github.com/yonghu86/SignalRTestProj

      5、參考文章


      一路走來數個年頭,感謝RDIFramework.NET框架的支持者與使用者,大家可以通過下面的地址了解詳情。

      RDIFramework.NET官方網站:http://www.rdiframework.net/

      RDIFramework.NET官方博客:http://blog.rdiframework.net/

      同時需要說明的,以后的所有技術文章以官方網站為準,歡迎大家收藏!

      RDIFramework.NET框架由海南國思軟件科技有限公司專業團隊長期打造、一直在更新、一直在升級,請放心使用!

      歡迎關注RDIFramework.net框架官方公眾微信(微信號:guosisoft),及時了解最新動態。

      掃描二維碼立即關注

      微信號:guosisoft

      posted @ 2019-08-26 11:15  .NET快速開發框架  閱讀(3070)  評論(1)    收藏  舉報
      主站蜘蛛池模板: 天美麻花果冻视频大全英文版| aa性欧美老妇人牲交免费| 崇明县| 国产熟睡乱子伦视频在线播放| 亚洲综合精品一区二区三区| 日韩乱码人妻无码中文字幕视频 | 日日猛噜噜狠狠扒开双腿小说| 色一伦一情一区二区三区| 91产精品无码无套在线| 亚洲一区二区三区在线观看精品中文| 伊人春色激情综合激情网| 亚洲爆乳少妇无码激情| 中国产无码一区二区三区| 国产四虎永久免费观看| 亚洲精品成人综合色在线| 成武县| 九九视频热最新在线视频| 中文字幕国产精品自拍| 亚洲欧美卡通另类丝袜美腿 | 亚洲av片在线免费观看| 国产aⅴ夜夜欢一区二区三区| 无码福利写真片视频在线播放| 国产精品国三级国产av| 久久av高潮av无码av喷吹| 国产精品日韩中文字幕熟女| 国产精品久久露脸蜜臀| 灵山县| 亚洲AV无码东方伊甸园| 色伦专区97中文字幕| 永久不封国产av毛片| 国产成人一区二区三区影院动漫| 99久久亚洲综合精品成人| 精品国产一区av天美传媒| 国产精品爆乳在线播放第一人称 | 堆龙德庆县| 国产精品美女免费无遮挡| 午夜性爽视频男人的天堂| 99久久久国产精品免费无卡顿| 国产亚洲av产精品亚洲| 狠狠色狠狠综合久久| 欧美一区二区三区成人久久片|