Asp.net SignalR的应用并实现群聊功能的实例详解

这篇文章主要为大家分享了asp.net signalr应用并实现群聊功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

ASP.NET SignalR 是为 ASP.NET 开发人员提供的一个库,可以简化开发人员将实时 Web 功能添加到应用程序的过程。实时 Web 功能是指这样一种功能:当所连接的客户端变得可用时服务器代码可以立即向其推送内容,而不是让服务器等待客户端请求新的数据。(来自官方介绍。)

SignalR官网

 -1、写这篇的原因

在上篇文章B/S(Web)实时通讯解决方案中,并没有详情介绍SignalR,所以另起一篇专门介绍SignalR,本文的侧重点是Hub功能。 

0、先看最终实现效果

Asp.net SignalR的应用并实现群聊功能的实例详解

github.com/Emrys5/SignalRGroupChatDemo

 1、准备工作

1.1、在NuGet上首先下载SignalR的包。

Asp.net SignalR的应用并实现群聊功能的实例详解

1.2、配置Owin与SignalR

1.2.1、新建Startup类,注册SignalR

public class Startup { public void Configuration(IAppBuilder app) {  app.MapSignalR(); } }

登录后复制

然后在web.config配置Startup类,在configuration=>appSettings节点中添加

1.2.2、在页面引入SignalR的js

1、由于SignalR前端是基于jQuery的,所以页面需引入jQuery。

2、引入SignalR的js 。

3、引入最重要的hubs js,这个js其实并不存在,SignalR会反射获取所有供客户端调用的方法放入hubs js中。

 

登录后复制

1.2.3、新建GroupChatHub类,并继承Hub抽象类

在hub类中的方法就是提供给客户端调用的js方法。

在js中就可以用signalr调用SendMsg。

[HubName("simpleHub")] public class SimpleHub : Hub {  public void SendMsg(string msg) { } }

登录后复制

这样基本上前期准备工作就做完了,后面就是具体的操作。

2、原理与简单的编程

其实原理如果简单点理解就很简单,因为http是无状态的,所以每次请求以后都会与服务器断开链接,那就是说客户端可以很容易找到服务器,但是服务器如果想给你客户端发送消息就比较麻烦,如果不明白的可以参考上一篇文章B/S(Web)实时通讯解决方案。

SignalR就很好的解决了这个问题,也就说实现了实现了浏览器与服务器的全双工通信。

2.1、客户端至服务端(B=>S)

客户端代码

  var ticker = $.connection.simpleHub; $.connection.hub.start(); $("#btn").click(function () { // 链接完成以后,可以发送消息至服务端 ticker.server.sendMsg("需要发送的消息"); }); 

登录后复制

服务端代码

[HubName("simpleHub")] public class SimpleHub : Hub { public void SendMsg(string msg) {  // 获取链接id  var connectionId = Context.ConnectionId;   // 获取cookie  var cookie = Context.RequestCookies; } }

登录后复制

其中SimpleHub就是我们定义的继承Hub类SimpleHub,然后我们可以用特性HubName进行重命名。

然后开始链接。

在链接完成以后,我们就可以调用在SimpleHub类中调用的方法。这就就很简单的实现了客户端至服务端发送消息。

Asp.net SignalR的应用并实现群聊功能的实例详解

我们还可以在Context中获取我们想要的东西,比如链接id,cookie等。

2.2、服务端至客户端(S=>B)

服务端代码

[HubName("simpleHub")] public class SimpleHub : Hub { public void SendMsg(string msg) {  Clients.All.msg("发送给客户端的消息");  } }

登录后复制

客户端代码

 var ticker = $.connection.groupChatHub; $.connection.hub.start(); ticker.client.msg = function (data) { console.log(data); } 

登录后复制

Asp.net SignalR的应用并实现群聊功能的实例详解

这里演示了怎么发送消息至客户端,也是SignalR比较重要的功能,这里有两个问题需要解决。

问题一、这里是发送消息给所有连着的客户端,如果是单个客户端或者是一批客户端应该怎么发送。

问题二、我们在调用msg给个客户端发送消息时是在接收消息以后做的反馈,然后发送消息给客户端,这样就很类似ajax了,服务端并没有主动给客户端发送消息。

解决:

问题一、Clients可以给特性的一群或者一个客户端发送消息

// 所有人Clients.All.msg("发送给客户端的消息"); // 特定 cooectionIdClients.Client("connectionId").msg("发送给客户端的消息");// 特定 groupClients.Group("groupName").msg("发送给客户端的消息");

登录后复制

这是比较常用的三个,当然还有很多,比如AllExcept,Clients。

在SignalR2.0中还添加了Others,OthersInGroup,OthersInGroups等等。

问题二、我们可以在需要发送消息的地方调用GlobalHost.ConnectionManager.GetHubContext().Clients中获取Clients。获取Clients并发送消息我们最好写成单例模式,因为这种需求很符合单例,群聊中有详细的代码。

3、SignalR实现群聊

以上的介绍和代码已经可以实现b=>s和s=>b了,那实现群聊和单独聊天就比较简单了。

由于功能比较简单,所有我把用户名存到了cookie里,也就说第一次进来时需要设置cookie。

还有就是在hub中要实现OnConnected、OnDisconnected和OnReconnected,然后在方法中设置用户和connectionid和统计在线用户,以便聊天使用。

hub代码

///  /// SignalR Hub 群聊类 ///  [HubName("groupChatHub")] // 标记名称供js调用 public class GroupChatHub : Hub { ///  /// 用户名 ///  private string UserName {  get  {  var userName = Context.RequestCookies["USERNAME"];  return userName == null ? "" : HttpUtility.UrlDecode(userName.Value);  } } ///  /// 在线用户 ///  private static Dictionary _onlineUser = new Dictionary(); ///  /// 开始连接 ///  ///  public override Task OnConnected() {  Connected();  return base.OnConnected(); } ///  /// 重新链接 ///  ///  public override Task OnReconnected() {  Connected();  return base.OnReconnected(); } private void Connected() {  // 处理在线人员  if (!_onlineUser.ContainsKey(UserName)) // 如果名称不存在,则是新用户  {  // 加入在线人员  _onlineUser.Add(UserName, 1);  // 向客户端发送在线人员  Clients.All.publshUser(_onlineUser.Select(i => i.Key));  // 向客户端发送加入聊天消息  Clients.All.publshMsg(FormatMsg("系统消息", UserName + "加入聊天"));  }  else  {  // 如果是已经存在的用户,则把在线链接的个数+1  _onlineUser[UserName] = _onlineUser[UserName] + 1;  }  // 加入Hub Group,为了发送单独消息  Groups.Add(Context.ConnectionId, "GROUP-" + UserName); } ///  /// 结束连接 ///  ///  ///  public override Task OnDisconnected(bool stopCalled) {  // 人员链接数-1  _onlineUser[UserName] = _onlineUser[UserName] - 1;  // 判断是否断开了所有的链接  if (_onlineUser[UserName] == 0)  {  // 移除在线人员  _onlineUser.Remove(UserName);  // 向客户端发送在线人员  Clients.All.publshUser(_onlineUser.Select(i => i.Key));  // 向客户端发送退出聊天消息  Clients.All.publshMsg(FormatMsg("系统消息", UserName + "退出聊天"));  }  // 移除Hub Group  Groups.Remove(Context.ConnectionId, "GROUP-" + UserName);  return base.OnDisconnected(stopCalled); } ///  /// 发送消息,供客户端调用 ///  /// 用户名,如果为0,则是发送给所有人 /// 消息 public void SendMsg(string user, string msg) {  if (user == "0")  {  // 发送给所有用户消息  Clients.All.publshMsg(FormatMsg(UserName, msg));  }  else  {  //// 发送给自己消息  //Clients.Group("GROUP-" + UserName).publshMsg(FormatMsg(UserName, msg));  //// 发送给选择的人员  //Clients.Group("GROUP-" + user).publshMsg(FormatMsg(UserName, msg));  // 发送给自己消息  Clients.Groups(new List { "GROUP-" + UserName, "GROUP-" + user }).publshMsg(FormatMsg(UserName, msg));  } } ///  /// 格式化发送的消息 ///  ///  ///  ///  private dynamic FormatMsg(string name, string msg) {  return new { Name = name, Msg = HttpUtility.HtmlEncode(msg), Time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") }; } }

登录后复制

js代码

 $(function () {  // 链接hub  var ticker = $.connection.groupChatHub;  $.connection.hub.start();  // 接收服务端发送的消息  $.extend(ticker.client, {  // 接收聊天消息  publshMsg: function (data) {   $("#msg").append("
  • " + data.Name + ":" + data.Msg + " " + data.Time + "") $("#msg").parents("p")[0].scrollTop = $("#msg").parents("p")[0].scrollHeight; }, // 接收在线人员,然后加入Select,以供单独聊天选中 publshUser: function (data) { $("#count").text(data.length); $("#users").empty(); $("#users").append('所有人'); for (var i = 0; i < data.length; i++) { $("#users").append('' + data[i] + '') } } }); // 发送消息按钮 $("#btn-send").click(function () { var msg = $("#txt-msg").val(); if (!msg) { alert('请输入内容!'); return false; } $("#txt-msg").val(''); // 主动发送消息,传入发送给谁,和发送的内容。 ticker.server.sendMsg($("#users").val(), msg); }); });
  • 登录后复制

    html代码

     群聊系统(1人在线):@ViewBag.UserName

     

    登录后复制 所有人

    这样就消息了群聊和发送给特定的人聊天功能。

    3.1、封装主动发送消息的单例

    ///  /// 主动发送给用户消息,单例模式 ///  public class GroupChat { ///  /// Clients,用来主动发送消息 ///  private IHubConnectionContext Clients { get; set; } private readonly static GroupChat _instance = new GroupChat(GlobalHost.ConnectionManager.GetHubContext().Clients); private GroupChat(IHubConnectionContext clients) {  Clients = clients; } public static GroupChat Instance {  get  {  return _instance;  } } ///  /// 主动给所有人发送消息,系统直接调用 ///  ///  public void SendSystemMsg(string msg) {  Clients.All.publshMsg(new { Name = "系统消息", Msg = msg, Time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") }); } }

    登录后复制

    如果需要发送消息,直接调用SendSystemMsg即可。

    GroupChat.Instance.SendSystemMsg(“消息”);

     4、结语

    啥也不说了直接源码

    github.com/Emrys5/SignalRGroupChatDemo

    以上就是 Asp.net SignalR的应用并实现群聊功能的实例详解的详细内容,更多请关注【创想鸟】其它相关文章!

    版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

    发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2443376.html

    (0)
    上一篇 2025年3月3日 14:06:06
    下一篇 2025年3月1日 16:31:52

    AD推荐 黄金广告位招租... 更多推荐

    相关推荐

    发表回复

    登录后才能评论