前言,如今这世道写篇帖子没个前言真很差意思发出来。本贴的主要内容来自于本人在以前项目中所开发的一个小功能,用于OA中的即时通信。因为当时走的太急,忘记把代码拿出来。想一想这已是大半年前的事情了,时间过了这么久,在当时最新的SignalR2.0.1到如今已经变成了2.2。昨天晚上特意熬了个夜,从新又把它写出来作了一个小小的Demo。固然我只是大天然的搬运工,这个SignalR即时通信功能里面有一些前端的类库不是我本身写的。我只是改吧改吧~~在此鸣谢 @贤心,是他的几条库才使得个人这个功能如此酷炫。前言猝!html
没个GIF的演示我会拿出来秀?前端
看上去是否是感受还能够? 那下面我讲解一下开发步骤。jquery
首先咱们打开VS2015(固然其它的版本也能够。我只是赶了个时髦,有天心血来潮就给安装了),再依次点击[文件]-[新建]-[项目]后弹出以下界面:app
咱们选择ASP.NET Web应用程序,而且将项目名称完善好,选择好项目保存路径。再点击肯定:ide
这里为了让等会的操做更加简单我直接选择了一个ASP.NET 4.5的 Empty 模板。并把下方的“为如下项目添加文件夹和核心引用”选择MVC。再点击肯定:函数
好了到这里风云突变狂风大做…一个活生生拥有着MVC核心引用和文件夹的项目已经展示在眼前。下面咱们就往项目中加入等会要使用到的SignalR。工具
这里用到了NuGet,网上也有不少资源讲解怎么使用这个。我这里只大概讲解一下。首先打开[工具]-[NuGet 程序包管理器]-[管理解决方案的 NuGet 程序包]spa
接下来在出现的界面中将程序包源改为:联机,而后搜索SignalR。接下来自行解决~.~.net
因为此时的项目仍是一个Empty的项目,须要经过Startup类来配置OWIN程序,因此要在项目中加入一个OWIN Startup类3d
建立好以后,再在Configuration函数中加入app.MapSignalR();
好了下面,咱们再为SignalR建立一个集线器Hubs,个人习惯是在项目中建立一个Hubs目录,而后把须要建立的HubClass放到里面。下面先在项目中建立一个Hubs目录,再在目录上单击右键选择[添加]-[新建项]选择[SignalR 集线器类]
点击肯定,再把新建的HubClass中的Hello函数干掉。而后在类上增长一个特性:[HubName("systemHub")]
。既然是要聊天那么天然离不开用户,为了方便管理我创建了一个用户的实体类UserDetail
1 /// <summary> 2 /// 用户细节 3 /// </summary> 4 public class UserDetail 5 { 6 /// <summary> 7 /// 链接ID 8 /// </summary> 9 public string ConnectionId { get; set; } 10 /// <summary> 11 /// 用户ID 12 /// </summary> 13 public string UserID { get; set; } 14 /// <summary> 15 /// 用户名 16 /// </summary> 17 public string UserName { get; set; } 18 /// <summary> 19 /// 用户部门 20 /// </summary> 21 public string DeptName { get; set; } 22 /// <summary> 23 /// 登陆时间 24 /// </summary> 25 public DateTime LoginTime { get; set; } 26 }
既然用户类有了,那么咱们能够在Hub里面建立一个用户池,用来管理在线用户。
1 public static List ConnectedUsers = new List();
如今用户池有了,下面须要实现三个功能就能进行登陆、上线、下线、私聊操做了。这是下面的逻辑处理代码:
1 /// <summary> 2 /// 登陆连线 3 /// </summary> 4 /// <param name="userID">用户ID</param> 5 /// <param name="userName">用户名</param> 6 /// <param name="deptName">部门名</param> 7 public void Connect(string userID, string userName, string deptName) 8 { 9 var id = Context.ConnectionId; 10 11 if (ConnectedUsers.Count(x => x.ConnectionId == id) == 0) 12 { 13 if (ConnectedUsers.Count(x => x.UserID == userID) > 0) 14 { 15 var items = ConnectedUsers.Where(x => x.UserID == userID).ToList(); 16 foreach (var item in items) 17 { 18 Clients.AllExcept(id).onUserDisconnected(item.ConnectionId, item.UserName); 19 } 20 ConnectedUsers.RemoveAll(x => x.UserID == userID); 21 } 22 //添加在线人员 23 ConnectedUsers.Add(new UserDetail { ConnectionId = id, UserID = userID, UserName = userName, DeptName = deptName, LoginTime = DateTime.Now }); 24 25 // 反馈信息给登陆者 26 Clients.Caller.onConnected(id, userName, ConnectedUsers); 27 28 // 通知全部用户,有新用户链接 29 Clients.AllExcept(id).onNewUserConnected(id, userID, userName, deptName, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); 30 31 } 32 else 33 { 34 35 } 36 } 37 38 /// <summary> 39 /// 发送私聊 40 /// </summary> 41 /// <param name="toUserId">接收方用户链接ID</param> 42 /// <param name="message">内容</param> 43 public void SendPrivateMessage(string toUserId, string message) 44 { 45 string fromUserId = Context.ConnectionId; 46 var toUser = ConnectedUsers.FirstOrDefault(x => x.ConnectionId == toUserId); 47 var fromUser = ConnectedUsers.FirstOrDefault(x => x.ConnectionId == fromUserId); 48 49 if (toUser != null && fromUser != null) 50 { 51 // send to 52 Clients.Client(toUserId).receivePrivateMessage(fromUserId, fromUser.UserName, message); 53 54 // send to caller user 55 //Clients.Caller.sendPrivateMessage(toUserId, fromUser.UserName, message); 56 } 57 else 58 { 59 //表示对方不在线 60 Clients.Caller.absentSubscriber(); 61 } 62 } 63 64 /// <summary> 65 /// 离线 66 /// </summary> 67 public override System.Threading.Tasks.Task OnDisconnected(bool stopCalled) 68 { 69 var item = ConnectedUsers.FirstOrDefault(x => x.ConnectionId == Context.ConnectionId); 70 if (item != null) 71 { 72 Clients.All.onUserDisconnected(item.ConnectionId, item.UserName); //调用客户端用户离线通知 73 ConnectedUsers.Remove(item); 74 } 75 return base.OnDisconnected(stopCalled); 76 }
我这里写的逻辑只是一个简单的示例,这个能够根据本身的想法和需求任意发挥。发挥时遇到问题也欢迎在留言一块儿交流。服务端代码完了,下面开始创建客户端代码。
到了这里咱们貌似尚未新建页面,访问会报404! 那么咱们先在Controllers目录上单击右键选择[添加]-[控制器]在弹出的界面中选择[MVC5控制器]
名字取成Home。而后把@贤心大神的弹层库等等库引用进来。把JS也引用进来。 在这时也能看到在Scripts目录下面有了几个SignalR的js文件。那么既然咱们建好Controller了下面就在HomeController的IndexAction上面单击右键选择[添加视图]在调用的时候须要注意的是要引用SignalR的内容:
1 <script src="~/Scripts/jquery.signalR-2.2.0.min.js"></script> 2 <script src="~/signalr/hubs"></script>
至于调用的方法也是比较简单的啦,下面附上简单的示例。更多详细的处理能够下载个人DEMO源码进行参考。
1 //实例SystemHub,首字母必须小写才能调用 2 var systemHub = $.connection.systemHub; 3 //开始连接到集线器 4 $.connection.hub.start().done(function () { 5 //调用服务端函数Connect(首字母小写)以及传递客户端参数进行上线操做 6 systemHub.server.connect(userid, username, deptname); 7 }); 8 //新用户上线 9 systemHub.client.onNewUserConnected = function (id, userID, userName, deptName, loginTime) { 10 //定义onNewUserConnected客户端函数供服务端调用 11 }; 12 //用户离线 13 systemHub.client.onUserDisconnected = function (id, userName) { 14 //定义onUserDisconnected客户端函数供服务端调用 15 }; 16 //发送消息时,对方已不在线 17 systemHub.client.absentSubscriber = function () { 18 //定义absentSubscriber客户端函数供服务端调用 19 }; 20 //接收消息 21 systemHub.client.receivePrivateMessage = function (fromUserId, userName, message) { 22 //定义receivePrivateMessage客户端函数供服务端调用 23 }; 24 //发送消息 25 systemHub.server.sendPrivateMessage(ChatCore.nowchat.id, data.content);
好了,关于MVC中使用SignalR的介绍也详细描述了,我只是抛砖引玉把本身之前开发的功能进行分享以及本身的温习。具体的源码在下方进行下载,若是以为内容不错,欢迎留言献花以示鼓励~~
源码下载:FangsiChat.zip
本文来自 放肆雷特 | 锋哥的技术博客