一步一步学习SignalR进行实时通信_5_Hub
一步一步学习SignalR进行实时通信\_5_Hub
SignalR
前言
上一讲,我们简单的介绍了下Hub的配置以及实现方法,这一将我希望把更多的细节梳理清楚,不至于让大家在细节上面摸不着头脑,理解深了,那么做项目自然就会相对轻松一些。
Hub命名规则
Hub与PersistentConnection很大的区别就是我们可以自己定义我们自己的方法,取我们想取得名字。
Hub的前台调用后台方法的命名规则遵循骆驼命名法,如果不遵循该约定,那么在程序中很有可能报错,在.net中约定大于配置已经是被人们普遍接受的了,它的好处是免去了大量的配置文件,而用一个公用的约定来完成,每个人只要遵循这个约定就不会出篓子。
比如在后台有这么一个方法
public void SendMessageByUserName(string userName)
{
...
}
那么在前台通过hub.server.sendMessageByUserName("name")
调用
如果后台方法改为
public void sendMessageByUserName(string userName)
{
...
}
在前台则用hub.server.sendmessageByUserName("name")
调用以此类推
在后台调用前台方法则无此约定,不区分大小写。因此假设后台你通过Clients.Caller.testHtmlClient();
调用前台的方法前台你可以写为hub.client.testHtmlClient()
,也可以写为hub.client.testhtmlclient()
甚至可以写为hub.client.teStHtMlClIENT()
Hub封装好的常用方法
假如我希望给指定姓名的人发送信息,Hub可以通过唯一的ConnectionId号发送给指定客户端,但是我们一般都是根据数据库中保存用户名或者数据库每条记录的Id进行数据操作。我们希望根据用户名来发送,那么我假设有一个字典保存了ConnectionId和UserName的对应关系
public class MySecondHub : Hub
{
private IDictionary<string, string> _userNames;
public MySecondHub()
{
//TODO:初始化UserNames
}
public void SendMessageByUserName(string userName)
{
//取到所有名字为那么的用户
IList<string> users = _userNames.Where(u => u.Value == userName).Select(u => u.Key).ToList();
Clients.Clients(users).sendMessage("Hi!");
}
}
那么在html页面我们可以通过 hub.server.sendMessageByUserName()
调用
<script type="text/javascript">
$(function () {
//创建一个hub服务
var hub = $.connection.myFirstHub;
$.connection.hub.start()
.done(function () {
alert("连接成功!");
})
$("#sayHello").click(function () {
hub.server.sendMessageByUserName("Jake");
});
hub.client.sendMessageByUserName = function(){
...
};
});
</script>
我们也可以修改前台调用方法的名字
...
//在前台可以通过sendMessageToGroup()调用
[HubMethodName("SendMessageToGroup")]
public void SendMessageByGroupName(string groupName)
{
Clients.Group(groupName);
}
这样在客户端我们就可以通过sendMessageToGroup()
调用SendMessageByGroupName()
方法了。
同时,我们传递的参数但可以是字符串也可以是复杂的类型,如:
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
public void SayHi(string name,string message)
{
var person = new Person(){Name = name,Message = message};
Clients.Others.sayHi(person);
}
前台代码,点击id为sayHello的按钮触发
...
$("#sayHello").click(function () {
hub.server.sayHi("jake","hah~");
});
hub.client.sayHi = function(person) {
$('#chat').append('<li><strong>' + person.Message + '</strong>:' + person.Name + '</li>');
};
...
之前我们讲到Client.Others.doSomething();
可以调用给报包括自己的所有其他客户端doSomething()方法,Hub还有许多其他的方法供我们调用
Hub常用方法解释
- Clients.Caller:可以与调用者进行通信
- Clients.Others:可以与除了自己以外所有连接上此Hub的客户端的通信
- Clients.All:可以与所有连接上此Hub的客户端通信
- Clients.OthersInGroup:可以与指定组以外的其他连接到Hub的客户端通信
- Clients.Client:可以与给指定ConnectionId的客户端进行通信
- Clients.AllExcept:可以与所有连接上此Hub但是除去指定ConnectionId以外的客户端通信
- Clients.Group:可以与在指定组的客户端通信
- Clients.User:可以与指定的userId进行通信
当然他们还有一些重载方法,这里就不一一介绍了,自己去试验下就能明白了。
PS:这里补充一个小知识,在MVC中已经实现了获取默认的UserId方法
public class PrincipalUserIdProvider : IUserIdProvider
{
public string GetUserId(IRequest request)
{
if (request == null)
throw new ArgumentNullException("request");
if (request.User != null && request.User.Identity != null)
return request.User.Identity.Name;
else return (string) null;
}
}
很多时候我们可能需要自己实现自己的方法,比如userId为登陆的userName,那么我们可以实现IUserIdProvider接口
public class CookiesUserIdProvider : IUserIdProvider
{
public string GetUserId(IRequest request)
{
if (request == null)
throw new ArgumentNullException("request");
Cookie cookie;
if (request.Cookies.TryGetValue("UserName", out cookie))
{
return cookie.Value;
}
else
{
return null;
}
}
}
当然我们还要告诉我们的项目使用我们自定义的提供器,而不是默认的,我们只需要在程序一开始,也就是Global中注册代码保证程序启动时调用即可。
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
...
//注册我们自己的Id提供器
GlobalHost.DependencyResolver.Register(typeof (IUserIdProvider), () => new CookiesUserIdProvider());
}
}
}
保持状态
在hub中可以通过hub.state
保存用户的状态
后台通过Client.Caller
获取前台传递来的参数运行项目断点,可以看到接收到的数据
参数名可以任意写,它是dynamic类型
前后台交互
难道保存状态只有这个用处吗?当然不止,这个状态还可以在某些情况下起到前后台交互的作用。
后台我们让Age++
然后前台在回调方法中我们在控制台中打印age,如果打印的是24,那么证明前后台数据能进行很好的交互而不仅仅是保存一个状态那么简单。
点击按钮后 通过firebug在控制台中可以看到打印出的是24
结束语
今天的文章知识点可能较零散,因为并没有一个实际例子来连接所有的知识,明天开始放假了,如果有时间的话希望能讲一个小例子来巩固一下。
源码下载
由于今天学习的都是些小细节,就不提供源码了。
本文发布至作业部落
参考文献
一步一步学习SignalR进行实时通信_5_Hub的更多相关文章
- 一步一步学习SignalR进行实时通信_1_简单介绍
一步一步学习SignalR进行实时通信\_1_简单介绍 SignalR 一步一步学习SignalR进行实时通信_1_简单介绍 前言 SignalR介绍 支持的平台 相关说明 OWIN 结束语 参考文献 ...
- 一步一步学习SignalR进行实时通信_8_案例2
原文:一步一步学习SignalR进行实时通信_8_案例2 一步一步学习SignalR进行实时通信\_8_案例2 SignalR 一步一步学习SignalR进行实时通信_8_案例2 前言 配置Hub 建 ...
- 一步一步学习SignalR进行实时通信_9_托管在非Web应用程序
原文:一步一步学习SignalR进行实时通信_9_托管在非Web应用程序 一步一步学习SignalR进行实时通信\_9_托管在非Web应用程序 一步一步学习SignalR进行实时通信_9_托管在非We ...
- 一步一步学习SignalR进行实时通信_7_非代理
原文:一步一步学习SignalR进行实时通信_7_非代理 一步一步学习SignalR进行实时通信\_7_非代理 SignalR 一步一步学习SignalR进行实时通信_7_非代理 前言 代理与非代理 ...
- 一步一步学习SignalR进行实时通信_6_案例
原文:一步一步学习SignalR进行实时通信_6_案例 一步一步学习SignalR进行实时通信\_6_案例1 一步一步学习SignalR进行实时通信_6_案例1 前言 类的定义 各块功能 后台 上线 ...
- 一步一步学习SignalR进行实时通信_4_Hub
原文:一步一步学习SignalR进行实时通信_4_Hub 一步一步学习SignalR进行实时通信\_4_Hub SignalR 一步一步学习SignalR进行实时通信_4_Hub 前言 创建Hub 配 ...
- 一步一步学习SignalR进行实时通信_3_通过CORS解决跨域
原文:一步一步学习SignalR进行实时通信_3_通过CORS解决跨域 一步一步学习SignalR进行实时通信\_3_通过CORS解决跨域 SignalR 一步一步学习SignalR进行实时通信_3_ ...
- 一步一步学习SignalR进行实时通信_2_Persistent Connections
原文:一步一步学习SignalR进行实时通信_2_Persistent Connections 一步一步学习SignalR进行实时通信\_2_Persistent Connections Signal ...
- 12.Linux软件安装 (一步一步学习大数据系列之 Linux)
1.如何上传安装包到服务器 有三种方式: 1.1使用图形化工具,如: filezilla 如何使用FileZilla上传和下载文件 1.2使用 sftp 工具: 在 windows下使用CRT 软件 ...
随机推荐
- 如何用EXCEL表计算今天是本年的第几周?
单元格内输入如下代码计算出来的数字即是当日在本年度的第几周,如下: =INT((TODAY()-DATE(YEAR(TODAY()),1,1)-WEEKDAY(DATE(YEAR(TODAY()),1 ...
- wampserver 2.2装好后80端口未被占用,却打不开localhost
在windows server 2003中装好wampserver2.2后打不开localhost,点击服务全部启动(颜色是橙色)也是打不开,我解决的原因是:安装mysql中sevice中的安装测试服 ...
- Turn the corner--hdu2438(3分法)
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission( ...
- codevs1040 统计单词个数
题目描述 Description 给出一个长度不超过200的由小写英文字母组成的字母串(约定;该字串以每行20个字母的方式输入,且保证每行一定为20个).要求将此字母串分成k份(1<k<= ...
- Node.js 参考学习地址
前段时间研究过Node.js 自从由于笔记本硬盘崩了之后就很少在家里搞程序了,但是很想学习之,只因最近在努力学习英文.技术之外的事也需要做好,我们毕竟不是为了技术而生,技术是我们生存的一门得力技能,唯 ...
- 开发SCM系统笔记001
使用EasyUI分页问题: 1.在分页界面没有显示声明分页属性名称,系统如何获取? EasyUI会向后台发送page\rows两个参数. 2.在配置sql参数时,parametertype与param ...
- jQuery提交form表单
<form id="search_form" name="search_form" method="post"> <inp ...
- Ubuntu12.04下jamvm1.5.4+classpath-0.98成功执行 helloworld.class
经过两天的努力,总于在ubuntu以下编译好classpath-0.98与jamvm1.5.4,并能成功的运行类文件:jamvm hellowold,当屏幕上打印出"hello world! ...
- 响应式流布局插件DyLay
jQuery插件-Dylay,流布局我们前面介绍过很多,但这个流布局jQuery插件不同的是它的动画效果很不错,大家可以尝试使用下.另外<有用的jQuery布局插件推荐>这篇文章中有好几个 ...
- 常用Java Web 服务器
Java Web应用程序需要部署在Java web服务器中运行,常用的Java Web服务器有Tomcat.GlassFish.WebLogic.JBoss.WebSphere.Jetty.JRun等 ...