博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用ASP.NET SignalR实现一个简单的聊天室
阅读量:7113 次
发布时间:2019-06-28

本文共 10282 字,大约阅读时间需要 34 分钟。

原文:

 前言

  距离我写上一篇博客已经又过了一年半载了,时间过得很快,一眨眼,就把人变得沧桑了许多。青春是短暂的,知识是无限的。要用短暂的青春,去学无穷无尽的知识,及时当勉励,岁月不待人。今天写个随笔小结记录一下。

 什么是SignalR?

  陌生的关键字,百度科普一下,什么是SignalR?ASP .NET SignalR 是一个ASP .NET 下的类库,可以在web中实现实时通信。服务器端可以将消息自动推送到已连接的客户端。官方网站SiR介绍写得很详细, 官网是英文的,如果像我一样看英文看的头疼的,可以像我一样试试把url中的  “en-us”改为 “zh-cn” 刷新即变成中文的了,

 

 

 

先看几个我做的效果图

 

 

 

 

这个聊天室,刚开始前端我用的是BootStrap,Css和页面布局我是拷贝了网上的别人改过的,直接搬过来用的,具体是哪里找的忘记了。。  QAQ。在此谢过了。聊天室中我实现了登录,公共聊天,组件群聊,私聊,消息推送,保存聊天记录等等功能。后来基本功能实现了后,前端我使用vue.js+webapi前后端分离了。

 

新建项目,SignalR入门

1)新建一个asp.net web项目,类型为MVC,取名为SignalRChat,然后在引用中添加NuGet浏览中安装SignalR。或者在工具栏中,程序包管理控制台输入如下语句安装SignalR:install-package Microsoft.AspNet.SignalR

2)  添加hub文件

 项目右键新建文件一个文件夹取名为Hubs,在该文件夹下新建一个Signalr集线类(v2),ChatHub类得上面自定义HubName,然后在 startup文件里配置hub路径,默认得HubName是该类名称开头字母小写

3)  建立一个 OWIN Startup 类来配置应用.

1 [assembly: OwinStartup(typeof(SignalRChat.Startup))] 2 namespace SignalRChat    3 { 4     public class Startup 5     { 6         public void Configuration(IAppBuilder app) 7         { 8             app.MapSignalR(); 9         }10     }11 }
View Code

 我的项目结构

Scripts中我只保留了必需用到的几个js,其他不必要的都删除,Model放实体类,common放公共类。SignalRContext类是自定义的一个类,用户保存在线用户的一些连接信息和房间信息等。没有涉及数据库,登陆数据是手动模拟造的数据。

重点在创建的ChatHub集线器中

1  [HubName("chatHub")] 2     public class ChatHub : Hub 3     { 4         #region 全局对象 5         protected static List
userInfoList = new List
(); 6 protected static SignalRContext DbContext = new SignalRContext(); 7 protected static List
chatHistoryList = new List
(); 8 #endregion 9 10 #region 连接11 12 ///
13 /// 客户端重连接时14 /// 15 ///
16 public override Task OnConnected()17 {18 AddUserGroup();//添加用户组19 UpdateAllRoomList();//更新房间列表20 21 return base.OnConnected();22 }23 ///
24 /// 断线25 /// 26 ///
27 ///
28 public override Task OnDisconnected(bool stopCalled)29 {30 return base.OnDisconnected(stopCalled);31 }32 #endregion
View Code

1)前端引用自动生成得集线器代理对象

var chat = $.connection.chatHub;注意红色标明得注意取 HubName中得名称,如果hubname没注释,就取集线器类中得类名首字母小写。

 2) 开始连接服务器

   $.connection.hub.start().done(function () {  });

公共聊天方法

1  #region 公共聊天 2  3         ///  4         /// 公共聊天 5         ///  6         ///  7         ///  8         public void PublicSendMsg(string message, string userId) 9         {10             var user = userInfoList.FirstOrDefault(x => x.UserID == userId);11             Clients.All.sendPublicMessage(user.UserID, user.UserName, message);12             AddChatHistory(ChatType.PubChat,user.UserName, message, user.UserID,"");//添加历史记录13         }14         #endregion
View Code

一对一聊天方法

1  ///  2         /// 发送私聊消息 3         ///  4         /// 发送名称 5         /// 用户id 6         /// 消息 7         public void SendPrivateMsg(string sendName, string userId, string message) 8         { 9             var toUser = userInfoList.FirstOrDefault(x => x.UserID == userId);//接收用户信息10             var fromUser = userInfoList.FirstOrDefault(x => x.ConnectionId == Context.ConnectionId);//发送用户信息11             if (toUser != null && fromUser != null)12             {13                 Clients.Caller.showMsgToPages(fromUser.UserID, sendName, message);14                 if (fromUser.UserID != userId)//判断是否是自己给自己发消息15                 {16                     Clients.Client(toUser.ConnectionId).remindMsg(fromUser.UserID, fromUser.UserName,message);17                 }18                 AddChatHistory(ChatType.PriChat, sendName, message, fromUser.UserID, userId, "");19             }20         }
View Code

多对多聊天,群聊方法 

1  ///  2         /// 创建聊天室 3         ///  4         ///  5         public void CreateRoom(string roomName) 6         { 7             var room = DbContext.Rooms.Find(x => x.RoomName == roomName); 8             if (room == null) 9             {10                 var rom = new ChatRoom11                 {12                     RoomName = roomName,13                     RoomId = Guid.NewGuid().ToString().ToUpper()14                 };15                 DbContext.Rooms.Add(rom);//加入房间列表16                 UpdateAllRoomList();//更新房间列表17                 Clients.Client(Context.ConnectionId).showGroupMsg("success");18             }19             else20             {21                 Clients.Client(Context.ConnectionId).showGroupMsg("error");22             }23         }24 25         /// 26         ///加入聊天室27         /// 28         public void JoinRoom(string roomId,string current_Id)29         {30             // 查询聊天室,31             var room = DbContext.Rooms.Find(x => x.RoomId == roomId.Trim());32             var u = userInfoList.Find(x => x.UserID == current_Id);33             if (room != null)34             {35                 //检测该用户是否存在在该房间36                 var isExistUser = room.Users.Find(x => x.UserConnectionId == Context.ConnectionId);37                 if (isExistUser == null)38                 {39                     var user = DbContext.Users.Find(x => x.UserConnectionId == Context.ConnectionId);40                     user.Rooms.Add(room);//用户信息中加入房间信息41                     room.Users.Add(user);//房间信息中加入用户信息42                     Groups.Add(Context.ConnectionId, room.RoomName);//添加到组中43                     Clients.Group(room.RoomName, new string[0]).showSysGroupMsg(u.UserName);44                 }45             }46             else47             {48                 Clients.Client(Context.ConnectionId).showMessage("该群组不存在");49             }50         }51 52         /// 53         /// 给指定房间内的所有用户发消息54         /// 55         /// 房间名56         /// 消息57         public void SendMessageByRoom(string roomId, string current_Id, string message)58         {59             var room = DbContext.Rooms.FirstOrDefault(x=>x.RoomId==roomId);60             var user = userInfoList.Find(x => x.UserID == current_Id);61             if (room != null && user != null)62             {63                 Clients.Group(room.RoomName, new string[0]).showGroupByRoomMsg(user.UserName,room.RoomId, message);64                 AddChatHistory(ChatType.GroChat, user.UserName, message, user.UserID, "", room.RoomId);65             }66         }67 68         /// 69         /// 退出房间70         /// 71         public void RemoveRoom(string roomId)72         {73             var room = DbContext.Rooms.Find(x => x.RoomId == roomId);74             if (room != null)75             {76                 var user = DbContext.Users.Find(x => x.UserConnectionId == Context.ConnectionId);77                 room.Users.Remove(user);//从房间里移除该用户78                 if (room.Users.Count <= 0)79                 {80                     DbContext.Rooms.Remove(room);//如果房间里没人了,删除该房间81                 }82                 Groups.Remove(Context.ConnectionId, room.RoomName);83                 UpdateAllRoomList();//更新房间列表84                 Clients.Client(Context.ConnectionId).removeRoom();85             }86             else87             {88                 Clients.Client(Context.ConnectionId).showMessage("该房间不存在");89             }90         }
View Code

 前端调用后台代码,使用  chat.server.方法名(参数1,参数2) 例如

1   // 开始连接服务器 2         $.connection.hub.start().done(function () { 3         $('#btnSend').click(function () { 4             var msg = $('#textMessage').val().trim(); 5             if (msg == "" || msg == undefined || msg == null) { 6                 alert("请输入聊天信息"); 7                 $('#textMessage').focus(); 8             } else { 9                 // 调用服务器端集线器的Send方法10                 chat.server.publicSendMsg(msg, current_userid);11                 // 清空输入框信息并获取焦点12                 $('#textMessage').val('').focus();13             }14         });
View Code

后台调用前端的代码。使用 chat.client.方法名。例如

1  //显示新用户加入消息2         chat.client.showJoinMessage = function (nickName) {3         $("#js-panel-content").append('
' + nickName + '加入了聊天
');4 }
View Code

 

 最后还有个保存和获取聊天记录的主要方法

1        //  2         /// 获取历史记录 3         ///  4         /// 消息类型0公共聊天,1好友,2群 5         /// 接收者id 6         /// 发送方id 7         /// 房间id 8         public void GetChatHistory(int chatType =(int)ChatType.PubChat,string toId="", string frmId="",string roomId="") 9         {10             var list = chatHistoryList;11             var type = (ChatType)chatType;12             switch (type)13             {14                 case ChatType.PubChat:15                     list = chatHistoryList.Where(x => x.ChatType == type).ToList();16                     break;17                 case ChatType.PriChat:18                     //自己发送给对方的,和对方发给自己的数据集合19                     list = chatHistoryList.Where(x => x.ChatType == type && ((x.toId == toId && x.frmId == frmId) || (x.toId == frmId && x.frmId == toId))).ToList();20                     break;21                 case ChatType.GroChat:22                     list = chatHistoryList.Where(x => x.ChatType == type && x.RoomId == roomId).ToList();23                     break;24                 default:25                     list = new List
();26 break;27 }28 var data = JsonHelper.ToJsonString(list);29 var user = userInfoList.FirstOrDefault(x=>x.UserID== frmId);30 var conid = Context.ConnectionId;31 if (user != null)32 {33 conid = user.ConnectionId;34 }35 Clients.Client(conid).initChatHistoryData(data, chatType);36 }37 ///
38 /// 添加历史记录数据39 /// 40 ///
41 ///
42 ///
0公共聊天,1私聊,2群聊43 public void AddChatHistory(ChatType chatType = 0,string userName="", string message="", string frmId="",string toId="",string roomId="")44 {45 ChatHistory history = new ChatHistory()46 {47 Hid = Guid.NewGuid().ToString().ToUpper(),48 ChatType = chatType,49 Message = message,50 UserName = userName,51 frmId = frmId,52 toId = toId,53 RoomId = roomId54 };55  chatHistoryList.Add(history);  以上就是一些主要核心代码。分享给大家共同学习,共同进步。

转载地址:http://qaghl.baihongyu.com/

你可能感兴趣的文章
如何引入vsconsole
查看>>
聚类算法(kmeans)详解和python实现
查看>>
时代在变,用户也在变,有温度的IP开发将成网络文学新趋势
查看>>
[ARKit]7-ARKit1.5的图片识别功能
查看>>
上线清单 —— 20 个 Laravel 应用性能优化项
查看>>
nvm 怎么安装 ?
查看>>
LeetCode 406 Queue Reconstruction by Height
查看>>
四种遍历方法你选哪个?
查看>>
LeetCode41.缺失的第一个正数 JavaScript
查看>>
Java设计模式五——单件模式
查看>>
CI第一篇 Jenkins+github fir im 蒲公英pgyer com
查看>>
webpack 搭建 vue 项目
查看>>
当TensorFlow遇上Kubernetes ---中兴通讯人工智能计算平台的技术实践
查看>>
奇怪的 Ruby
查看>>
PAT A1084
查看>>
79. Word Search
查看>>
【Android】RxJava的使用(四)线程控制 —— Scheduler
查看>>
极限编程 (Extreme Programming) - 迭代计划 (Iterative Planning)
查看>>
小程序外卖购物车 直接就能用~
查看>>
Python版设计模式之监听者模式
查看>>