用SignalR 2.0开发客服系统[系列2:实现聊天室]

前言

上周发表了

用SignalR 2.0开发客服系统[系列1:实现群发通讯]

这篇文章,得到了很多帮助和鼓励,小弟在此真心的感谢大家的支持..

这周继续系列2,实现聊天室的功能.

开发环境

开发工具:VS2013 旗舰版

数据库:未用

操作系统:WIN7旗舰版

正文开始

首先我们来看看最终效果:

正式开始:

SignalR作为一个强大的集线器,已经在hub里面集成了Gorups,也就是分组管理,使用方法如下:

//作用:将连接ID加入某个组
//Context.ConnectionId 连接ID,每个页面连接集线器即会产生唯一ID
//roomName分组的名称
Groups.Add(Context.ConnectionId, roomName);

//作用:将连接ID从某个分组移除
Groups.Remove(Context.ConnectionId, roomName);

//作用:调用分组内连接对象注册的本地JS
//XXX:本地JS名称
//Room:分组名称
// new string[0]:过滤(不发送)的连接ID数组
 Clients.Group(Room, new string[0]).XXXX

其实SignalR已经帮我们封装的很好了,关键代码其实就这三句..

废话不多说,下面开始讲我的实现.

首先实体类(参考微软Demo):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
using System.ComponentModel.DataAnnotations;
using Microsoft.AspNet.SignalR;
namespace SignalRTest
{
  public class UserContext 
  {
    public UserContext()
    {
      Users = new List<User>();
      Connections = new List<Connection>();
      Rooms = new List<ConversationRoom>();
    }
    //用户集合
    public List<User> Users { get; set; }
    //连接集合
    public List<Connection> Connections { get; set; }
    //房间集合
    public List<ConversationRoom> Rooms { get; set; }
  }
  public class User
  {
    [Key]
    //用户名
    public string UserName { get; set; }
    //用户的连接
    public List<Connection> Connections { get; set; }
    //用户房间集合
    public virtual List<ConversationRoom> Rooms { get; set; }
    public User()
    {
      Connections = new List<Connection>();
      Rooms = new List<ConversationRoom>();
    }
  }
  public class Connection
  {
    //连接ID
    public string ConnectionID { get; set; }
    //用户代理
    public string UserAgent { get; set; }
    //是否连接
    public bool Connected { get; set; }
  }
  /// <summary>
  /// 房间类
  /// </summary>
  public class ConversationRoom
  {
    //房间名称
    [Key]
    public string RoomName { get; set; }
    //用户集合
    public virtual List<User> Users { get; set; }
    public ConversationRoom()
    {
      Users = new List<User>();
    }
  }
}

然后聊天室的Hub(这里我就不解释了,每句话我都加了注释,注释+代码方便大家理解..):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.AspNet.SignalR;
using System.Threading.Tasks;
using Microsoft.AspNet.SignalR.Hubs;
using Newtonsoft.Json;
namespace SignalRTest
{
  [HubName("groupsHub")]
  public class GroupsHub : 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);
    }
    /// <summary>
    /// 重写Hub连接断开的事件
    /// </summary>
    /// <returns></returns>
    public override Task OnDisconnected()
    {
       var user = db.Users.Where(u => u.UserName == Context.ConnectionId).FirstOrDefault();
        //判断用户是否存在,存在则删除
        if (user != null)
        {
          //删除用户
          db.Users.Remove(user);
          // 循环用户的房间,删除用户
          foreach (var item in user.Rooms)
          {
            RemoveFromRoom(item.RoomName);
          }
        }
      return base.OnDisconnected();
    }
    /// <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());
    }
  }
}

前端HTML+JS:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  <title></title>
  <script src="Scripts/jquery-1.10.2.min.js"></script>
  <script src="Scripts/jquery.signalR-2.0.0.min.js"></script>
  <!--这里要注意,这是虚拟目录,也就是你在OWIN Startup中注册的地址-->
  <script src="signalr/hubs"></script>
  <script>
    var chat
    var roomcount = 0;
    $(function () {
        chat = $.connection.groupsHub;
        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 = '<div style="float:left; margin-left:30px; border:double" id="' + roomname + '" roomname="' + roomname + '"><button οnclick="RemoveRoom(this)">退出</button>\
                  ' + roomname + '房间\
                        聊天记录如下:<ul>\
                        </ul>\
                  <input type="text" /> <button οnclick="SendMessage(this)">发送</button>\
                  </div>'
          $("#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+'" οnclick="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");
      chat.server.removeFromRoom(roomname);
    }
    function AddRoom(roomname) {
       var data =$(roomname).attr("roomname");
       chat.server.addToRoom(data);
    }
  </script>
</head>
<body>
  <div>
    <div>名称:<p id="username"></p></div>
    输入房间名:
    <input type="text" value="asdasd" id="Roomname" />
    <button id="CreatRoom">创建聊天室</button>
  </div>
  <div style="float:left;border:double">
    <div>房间列表</div>
    <ul id="roomlist">
    </ul>
  </div>
  <div id="RoomList">
  </div>
</body>
</html>

至此就完成了基本的聊天室功能,有许多逻辑写的不到位的情况,请大家海涵.

我会坚持写完本系列..

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值