前言
距离我写上一篇博客已经又过了一年半载了,时间过得很快,一眨眼,就把人变得沧桑了许多。青春是短暂的,知识是无限的。要用短暂的青春,去学无穷无尽的知识,及时当勉励,岁月不待人。今天写个随笔小结记录一下。
什么是SignalR?
陌生的关键字,百度科普一下,什么是SignalR?ASP .NET SignalR 是一个ASP .NET 下的类库,可以在web中实现实时通信。服务器端可以将消息自动推送到已连接的客户端。官方网站SignalR介绍写得很详细, http://www.asp.net/signalr/overview/getting-started/tutorial-getting-started-with-signalr 官网是英文的,如果像我一样看英文看的头疼的,可以像我一样试试把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 }
我的项目结构
Scripts中我只保留了必需用到的几个js,其他不必要的都删除,Model放实体类,common放公共类。SignalRContext类是自定义的一个类,用户保存在线用户的一些连接信息和房间信息等。没有涉及数据库,登陆数据是手动模拟造的数据。
重点在创建的ChatHub集线器中
1 ?[HubName("chatHub")] 2 ????public class ChatHub : Hub 3 ????{ 4 ????????#region 全局对象 5 ????????protected static List<UserInfo> userInfoList = new List<UserInfo>(); 6 ????????protected static SignalRContext DbContext = new SignalRContext(); 7 ????????protected static List<ChatHistory> chatHistoryList = new List<ChatHistory>(); 8 ????????#endregion 9 10 ????????#region 连接11 ??????12 ????????/// <summary>13 ????????/// 客户端重连接时14 ????????/// </summary>15 ????????/// <returns></returns>16 ????????public override Task OnConnected()17 ????????{18 ????????????AddUserGroup();//添加用户组19 ????????????UpdateAllRoomList();//更新房间列表20 21 ????????????return base.OnConnected();22 ????????}23 ????????/// <summary>24 ????????/// 断线25 ????????/// </summary>26 ????????/// <param name="stopCalled"></param>27 ????????/// <returns></returns>28 ????????public override Task OnDisconnected(bool stopCalled)29 ????????{30 ????????????return base.OnDisconnected(stopCalled);31 ????????}32 ????????#endregion
1)前端引用自动生成得集线器代理对象
var chat = $.connection.chatHub;注意红色标明得注意取 HubName中得名称,如果hubname没注释,就取集线器类中得类名首字母小写。
2) 开始连接服务器
$.connection.hub.start().done(function () { });
公共聊天方法
1 ?#region 公共聊天 2 ?3 ????????/// <summary> 4 ????????/// 公共聊天 5 ????????/// </summary> 6 ????????/// <param name="message"></param> 7 ????????/// <param name="name"></param> 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
一对一聊天方法
1 ?/// <summary> 2 ????????/// 发送私聊消息 3 ????????/// </summary> 4 ????????/// <param name="sendName">发送名称</param> 5 ????????/// <param name="userId">用户id</param> 6 ????????/// <param name="message">消息</param> 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 ????????}
多对多聊天,群聊方法
1 ?/// <summary> 2 ????????/// 创建聊天室 3 ????????/// </summary> 4 ????????/// <param name="roomName"></param> 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 ????????/// <summary>26 ????????///加入聊天室27 ????????/// </summary>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 ????????/// <summary>53 ????????/// 给指定房间内的所有用户发消息54 ????????/// </summary>55 ????????/// <param name="room">房间名</param>56 ????????/// <param name="message">消息</param>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 ????????/// <summary>69 ????????/// 退出房间70 ????????/// </summary>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 ????????}
前端调用后台代码,使用 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 ????????});
后台调用前端的代码。使用 chat.client.方法名。例如
1 ?//显示新用户加入消息2 ????????chat.client.showJoinMessage = function (nickName) {3 ????????$("#js-panel-content").append(‘<div class="js-time text-white text-center"><span>‘ + nickName + ‘加入了聊天</span></div>‘);4 ????}
最后还有个保存和获取聊天记录的主要方法
1 ???????// <summary> 2 ????????/// 获取历史记录 3 ????????/// </summary> 4 ????????/// <param name="chatType">消息类型0公共聊天,1好友,2群</param> 5 ????????/// <param name="toId">接收者id</param> 6 ????????/// <param name="frmId">发送方id</param> 7 ????????/// <param name="roomId">房间id</param> 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<ChatHistory>();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 ????????/// <summary>38 ????????/// 添加历史记录数据39 ????????/// </summary>40 ????????/// <param name="name"></param>41 ????????/// <param name="message"></param>42 ????????/// <param name="chatType">0公共聊天,1私聊,2群聊</param>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);
以上就是一些主要核心代码。分享给大家共同学习,共同进步。
使用ASP.NET SignalR实现一个简单的聊天室
原文地址:https://www.cnblogs.com/wwym/p/8780798.html