MVC中使用SignalR
MVC中使用SignalR打造酷炫实用的即时通讯功能附源码
前言,现在这世道写篇帖子没个前言真不好意思发出来。本贴的主要内容来自于本人在之前项目中所开发的一个小功能,用于OA中的即时通讯。由于当时走的太急,忘记把代码拿出来。想想这已经是大半年前的事情了,时间过了这么久,在当时最新的SignalR2.0.1到现在已经变成了2.2。昨天晚上特地熬了个夜,重新又把它写出来做了一个小小的Demo。当然我只是大自然的搬运工,这个SignalR即时通讯功能里面有一些前端的类库不是我自己写的。我只是改吧改吧~~在此鸣谢 @贤心,是他的几条库才使得我的这个功能如此酷炫。前言猝!
最终效果演示
没个GIF的演示我会拿出来秀?

看上去是不是感觉还可以? 那下面我讲解一下开发步骤。
创建MVC项目
首先我们打开VS2015(当然其它的版本也可以。我只是赶了个时髦,有天心血来潮就给安装了),再依次点击[文件]-[新建]-[项目]后弹出如下界面:

我们选择ASP.NET Web应用程序,并且将项目名称完善好,选择好项目保存路径。再点击确定:

这里为了让等会的操作更加简单我直接选择了一个ASP.NET 4.5的 Empty 模板。并把下方的“为以下项目添加文件夹和核心引用”选择MVC。再点击确定:

好了到这里风云突变狂风大作…一个活生生拥有着MVC核心引用和文件夹的项目已经展现在眼前。下面我们就往项目中加入等会要使用到的SignalR。
为MVC项目在NuGet中引用SignalR
这里用到了NuGet,网上也有很多资源讲解怎么使用这个。我这里只大概讲解一下。首先打开[工具]-[NuGet 程序包管理器]-[管理解决方案的 NuGet 程序包]

接下来在出现的界面中将程序包源改成:联机,然后搜索SignalR。接下来自行解决~.~
使用SignalR
由于此时的项目还是一个Empty的项目,需要通过Startup类来配置OWIN程序,所以要在项目中加入一个OWIN Startup类

创建好之后,再在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 }

我这里写的逻辑只是一个简单的示例,这个可以根据自己的想法和需求任意发挥。发挥时遇到问题也欢迎在留言一起交流。服务端代码完了,下面开始建立客户端代码。
客户端调用SignalR
到了这里我们貌似还没有新建页面,访问会报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
MVC中使用SignalR的更多相关文章
- MVC中使用SignalR打造酷炫实用的即时通讯功能附源码
前言,现在这世道写篇帖子没个前言真不好意思发出来.本贴的主要内容来自于本人在之前项目中所开发的一个小功能,用于OA中的即时通讯.由于当时走的太急,忘记把代码拿出来.想想这已经是大半年前的事情了,时间过 ...
- MVC 中使用 SignalR 实现推送功能
MVC 中使用 SignalR 实现推送功能 一,简介 Signal 是微软支持的一个运行在 Dot NET 平台上的 html websocket 框架.它出现的主要目的是实现服务器主动推送(Pus ...
- 在MVC中使用SignalR
在MVC中使用SignalR 接着上一篇:<ASP.NET SignalR系列>第四课 SignalR自托管(不用IIS) 一.概述 本教程主要阐释了如何在MVC下使用ASP.NET Si ...
- 在 Asp.NET MVC 中使用 SignalR 实现推送功能 [转]
在 Asp.NET MVC 中使用 SignalR 实现推送功能 罗朝辉 ( http://blog.csdn.net/kesalin ) CC许可,转载请注明出处 一,简介 Signal 是微软支持 ...
- MVC中使用SignalR打造酷炫实用的即时通讯功能(轉載)
資料來源:http://www.fangsi.net/1144.html 前言,现在这世道写篇帖子没个前言真不好意思发出来.本贴的主要内容来自于本人在之前项目中所开发的一个小功能,用于OA中的即时通讯 ...
- 《ASP.NET SignalR系列》第五课 在MVC中使用SignalR
接着上一篇:<ASP.NET SignalR系列>第四课 SignalR自托管(不用IIS) 一.概述 本教程主要阐释了如何在MVC下使用ASP.NET SignalR. 添加Signal ...
- Asp.NET MVC 中使用 SignalR 实现推送功能
一,简介Signal 是微软支持的一个运行在 Dot NET 平台上的 html websocket 框架.它出现的主要目的是实现服务器主动推送(Push)消息到客户端页面,这样客户端就不必重新发送请 ...
- 在 Asp.NET MVC 中使用 SignalR 实现推送功能
一,简介Signal 是微软支持的一个运行在 Dot NET 平台上的 html websocket 框架.它出现的主要目的是实现服务器主动推送(Push)消息到客户端页面,这样客户端就不必重新发送请 ...
- [置顶]
MVC中使用signalR入门教程
一.前言:每次写总要说一点最近的感想 进入工作快半年了,昨天是最郁闷的一天,我怀疑我是不是得了"星期一综合征",每个星期一很没有状态.全身都有点酸痛,这个可能一个星期只有周末才打一 ...
随机推荐
- ZOJ 2680 Clock()数学
主题链接:problemId=1680" target="_blank">http://acm.zju.edu.cn/onlinejudge/showProblem ...
- centos6.4设备hadoop-2.5.1(完全分布式)
环境介绍: 在这两种装备centos6.4(32位置)的server安装Hadoop-2.5.1分布式集群(2台机器,主要试验用.哈哈). 1.改动主机名和/etc/hosts文件 1)改动主机名(非 ...
- springmvc+mongodb+maven 项目测试代码
你看我有一篇文章配置,或许还会有.mongodb性能测试结果.一个"快"字 源代码包,请留下邮箱 代码结构图 watermark/2/text/aHR0cDovL2Jsb2cuY3 ...
- CSAPP 六个重要的实验 lab5
CSAPP && lab5 实验指导书: http://download.csdn.net/detail/u011368821/7951657 实验材料: http://downlo ...
- Hadoop-2.2.0中文文档—— MapReduce下一代- 可插入的 Shuffle 和 Sort
简单介绍 可插入的 shuffle 和 sort 功能,同意在shuffle 和 sort 逻辑中用可选择的实现类替换.这个情况的样例是:用一个不是HTTP的应用协议,如RDMA来 shuffle 从 ...
- UVA - 12130 Summits
Description Problem G - Summits Time limit: 8 seconds You recently started working for the largest m ...
- AndroidAnnotations说明—AndroidAnnotations它是如何工作的?
AndroidAnnotations它的工作原理很easy,它使用标准java注塑加工工具,自己主动加她一个额外的步骤生成源代码编译. 源代码是什么?每个增强的类.比方每个用@EAct ...
- hdu3182 状态压缩水题
题意是这种 给你n个汉堡 每一个汉堡有它的价值 做每一个汉堡都得花费相应的能量 如今告诉你最大能量 让你求获得的最大的价值(有些汉堡必须有还有一些汉堡做好为前提) 给你的 ...
- cocos2d-html5
cocos2d-html5 简单的混乱 在正常情况下,build设置完毕后 跑ant编 变更后cocos2d.js 简单直观so easy 只需要上传cocos2d.js/game.js/index文 ...
- android:强大的图像下载和缓存库Picasso
1.Picasso一个简短的引论 Picasso它是Square该公司生产的一个强大的图像下载并缓存画廊.官方网站:http://square.github.io/picasso/ 仅仅须要一句代码就 ...