一、连接的生命周期设置:

如下:

            // 该值表示连接在超时之前保持打开状态的时间长度。
            //默认为110秒
            GlobalHost.Configuration.ConnectionTimeout = TimeSpan.FromSeconds(110);

            //该值表示在连接停止之后引发断开连接事件之前要等待的时间长度。
            //默认为30秒
            GlobalHost.Configuration.DisconnectTimeout = TimeSpan.FromSeconds(30);

            //用于表示两次发送保持活动消息之间的时间。如果启用,此值必须至少为两秒。设置为 null 可禁用。
            //默认为10秒,设置DisconnectTimeout后默认为DisconnectTimeout的3分之一
            GlobalHost.Configuration.KeepAlive = TimeSpan.FromSeconds(10);

注意一点,这些配置是写在你的Global.asax的Application_Start()方法中的,切勿写在Owin启动器中..

二、如何在服务器的其他类中使用Hub:

如下:

using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace SignalRTest
{
    public class Class1
    {
        //获取相关的集线器
        Microsoft.AspNet.SignalR.IHubContext context = Microsoft.AspNet.SignalR.GlobalHost.ConnectionManager.GetHubContext<SignalRTest.MoveTextHub>();

     public void aaa(string message)
        {

            context.Clients.All.broadcastMessage(message + DateTime.Now.ToString());
        }
    }
}

三、使用自己的连接ID

老规矩,前言~,在此先道个歉,之前的1-5对很多细节问题都讲的不是很详细,也有很多人在QQ或者博客问我一些问题

所以,特开了这个续集.. - -, 讲一些大家在开发中遇到的问题和一些解决方案,今天就来说说经常被问到的,如何使用自己定义的连接ID.

之前我们说过,Signalr提供了唯一的连接ID 获取方法:Context.ConnectionId,

那么怎么自己定义这个东西呢? (废话一堆 - - ,),进入主题:

首先,其实在Signalr的前期版本是可以直接自定义Context.ConnectionId,

使用老版本的可以自行查看IConnectionIdGenerator, IConnectionIdFactory 这两个接口.

所以特意说明一下,本博客这里的代码,只适用于Signalr2.0以上版本

其实在2.0的版本中,SignalR团队为了安全性,已经完全去除了自定义Context.ConnectionId的接口,但是相应的开放了相对安全的IUserIdProvider

废话不多说,直接上代码:

首先帐户登陆的代码:

其实就是很传统的登陆代码..把一些用户信息写入到Cookie中而已.黄色为重点

    public class UserController : ApiController
    {
        [HttpGet]
        public object Login(string name,string pwd)
        {
           UserInfoBLL bll = new UserInfoBLL();
           if (CacheHelper.Get(name) == null)
           {
               var userinfo = bll.LoginUser(name, pwd);

               if (userinfo != null)
               {

                   var context = HttpContext.Current;
                   //帐户信息写入Cookie,自行加密
                   context.Response.Cookies.Add(new HttpCookie(UserEnum.INFO) { Value = JsonConvert.SerializeObject(userinfo) });                   //唯一的登陆ID,作为连接ID
                   context.Response.Cookies.Add(new HttpCookie(UserEnum.SignalRID) { Value = userinfo.LoginName });

                   return new { State=true,Message="登陆成功!"};
               }
               else
               {
                   return new { State=false,Message="帐户或密码输入错误!"};
               }
           }
           else
           {
               return new { State=false,Message="该帐户已经登陆!"};
           }

        }

    }

接下来实现IUserIdProvider:

    public class MyUserFactory : IUserIdProvider
    {

        public string GetUserId(IRequest request)
        {
            if (request.GetHttpContext().Request.Cookies[UserEnum.SignalRID] != null)
            {
                return request.GetHttpContext().Request.Cookies[UserEnum.SignalRID].Value;
            }
            return "";
           // return Guid.NewGuid().ToString();
        }
    }

以上代码是创建一个MyUserFactory类,继承自IUserIdProvider,实现IUserIdProvider的抽象方法GetUserId

这里的ID我们从Cookies中获取,细心的人应该已经发现了,有个IRequest的参数,所以原则上你可以使用IRequest的各种属性比如QS..你随意..(注:Session暂时无法使用,原因未知)

接下来,重点来了..

在Starup中,把我们自定义的MyUserFactory注入到回话设置中..

代码如下(黄色为重点):

 public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            // 有关如何配置应用程序的详细信息,请访问 http://go.microsoft.com/fwlink/?LinkID=316888

            //重点,将MyUserFactory注入
            var userIdProvider = new MyUserFactory();
            GlobalHost.DependencyResolver.Register(typeof(IUserIdProvider), () => userIdProvider);

             //设置Webapi
            var config = new HttpConfiguration();
            config.Routes.MapHttpRoute(name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new
                {
                    id = RouteParameter.Optional
                });
            System.Web.HttpContext.Current.SetSessionStateBehavior(System.Web.SessionState.SessionStateBehavior.Required);
            app.UseWebApi(config);
            app.MapSignalR();
        }
    }

接下来在Hub中添加代码如下:

            /// <summary>
            /// 获取连接ID,你可以写成自己的扩展方法,或设置成属性,自行定义
            /// </summary>
            /// <returns></returns>
            public string GetSignalrID()
            {
                if (Context.Request.GetHttpContext().Request.Cookies[UserEnum.SignalRID] != null)
                {
                    return Context.Request.GetHttpContext().Request.Cookies[UserEnum.SignalRID].Value;
                }
                return "";
            }
            //编写发送信息的方法
            public void SendMessage(string message)
            {

                string id = Context.ConnectionId;
                string username = Context.User.Identity.Name;
                var userinfo = JsonConvert.DeserializeObject<UserInfo>(Context.Request.GetHttpContext().Request.Cookies[UserEnum.INFO].Value);
                 var Message = new
                        {
                            name = userinfo.UserName,
                            loadname = userinfo.LoginName,
                            picurl = userinfo.UserPicUrl,
                            time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
                            message = message
                        };

                        Clients.User(GetSignalrID()).broadcastMessage(Message);
            }

说明:重点是标黄色的地方,看过我之前文章的都知道,之前我们的对指定连接对象发送数据,写法为: Clients.Client("连接ID").客户端方法,

这里我们换成了Clients.User("自定义ID"),这样就完成了整个使用自己的连接ID的替换工作.

参考资料:

http://www.cnblogs.com/GuZhenYin/p/4744786.html

SignalR2.0开发实例之——设置时间、后台其他地方使用集线器、使用自己的连接ID的更多相关文章

  1. SignalR2.0开发实例之——私聊

    一.前言 继续上一章的补充,这章介绍使用私聊的功能.主要通过一个方法   Clients.Client(Context.ConnectionId).showMessage(msg); SignalR框 ...

  2. SignalR2.0开发实例之——群发消息

    一.前言 ASP .NET SignalR 是一个ASP .NET 下的类库,可以在ASP .NET 的Web项目中实现实时通信.什么是实时通信的Web呢?就是让客户端(Web页面)和服务器端可以互相 ...

  3. SignalR2.0开发实例之——创建房间聊天

    SignalR作为一个强大的集线器,已经在hub里面集成了Gorups,也就是分组管理,使用方法如下: //作用:将连接ID加入某个组 //Context.ConnectionId 连接ID,每个页面 ...

  4. SignalR2.0开发实例之——负载均衡

    SignalR 2.0作为一个新的而且强大的通信工具,发布博客之后得到了很多人的支持,谢谢...也有人对性能和架设等问题提出了各种质疑..真的很感谢.. 我特意下载了SignalR 2.0的源码硬着头 ...

  5. 一篇对OAuth2.0开发实例的介绍

    今天看到了博友对SSO的文章,SSO单点登录的讲解突然想写一篇关于OAuth2.0用户授权的介绍. 应用场景:在APP或者网页接入一些第三方应用时,时长会需要用户登录另一个合作平台,比如QQ,微博,微 ...

  6. 基于Cocos2d-x-1.0.1的飞机大战游戏开发实例(中)

    接<基于Cocos2d-x-1.0.1的飞机大战游戏开发实例(上)> 三.代码分析 1.界面初始化 bool PlaneWarGame::init() { bool bRet = fals ...

  7. Vuejs实例-00Vuejs2.0全家桶结合ELementUI制作后台管理系统

    Vuejs2.0全家桶结合ELementUI制作后台管理系统 0: 系统环境的介绍 1: Vuejs实例-01使用vue-cli脚手架搭建Vue.js项目 2: Vuejs实例-02Vue.js项目集 ...

  8. 【eclipse插件开发实战】 Eclipse插件开发5——时间插件Timer开发实例详解

    Eclipse插件开发5--时间插件Timer开发实例详解 这里做的TimeHelper插件设定为在菜单栏.工具栏提供快捷方式,需要在相应地方设置扩展点,最后弹出窗体显示时间. 在上一篇文章里创建好了 ...

  9. 【Android 开发实例】时间管理APP开发之数据库设计

    当然也能够先写界面什么的.可是,总认为先把数据库后台写好在写界面比較放心. 对于数据库的设计,我一開始没什么概念.甚至不知道怎样下手,一開始想着设计成几个表?有哪些字段? 最后用了两天时间,还是一无所 ...

随机推荐

  1. CentOS下安装nginx并且升级nginx到最新版

    yum install yum-fastestmirro yum install nginxyum update nginx(之前先配置一下)vim /etc/yum.repos.d/nginx.re ...

  2. smarty 中时间格式化的用法

    大家都知道PHP中输出时间和日期可以用 date("Y-m-d H:i:s",时间戳)  , 但是在smarty模板中,$time|date_format:'%Y-%m-%d %H ...

  3. ubuntu 14.下 netbeans 自体锯齿 消除

    Ubuntu下NetBeans消除字体锯齿的方法 在netbeans.conf 文件的netbeans_default_options的最后添加 -J-Dswing.aatext=true -J-Da ...

  4. d3可视化实战04:事件绑定机制

    首先说明,d3支持所有的JS事件——甚至其他代码的自定义事件.这里有一个列表,The MDN Event Reference, 包含了几乎所有浏览器创建的事件类型.大家有需要可以去查看. D3的事件绑 ...

  5. XJOI网上同步测试DAY14 T1

    思路:线段树维护最短路 #include<cstdio> #include<cmath> #include<iostream> #include<algori ...

  6. C++11之后,对源代码增加了UTF8和UCS4的支持(Windows内部使用Unicode,因为nt内核用的是ucs2,那是89年,utf8到了92年才发明出来)

    在C++编程中, 我们常打交道的无非是编辑器和编译器, 对编辑器起来说,我们常遇到就是乱码问题, 比如中文注释显示或是保存不了等, 解决办法就是把你的文件保存成Unicode(UTF8). 对于编译器 ...

  7. 如何判断一个C++对象是否在堆上(通过GetProcessHeaps取得所有堆,然后与对象地址比较即可),附许多精彩评论

    在帖子如何判断一个C++对象是否在堆栈上 中, 又有人提出如何判断一个C++对象是否在堆上. 其实我们可以参照那个帖子的方法类似实现,我们知道堆就是Heap,在windows上我们可以通过GetPro ...

  8. 许多js框架或js库的min版本是怎么做出来的?

    如jQuery,Bootstrap,AngularJs,这些都有min版本,代码更加精简,功能却相同.看了源代码,几乎不可读. 这种事情的工具类型叫做“minifier”.请看传送门:Minifica ...

  9. C++中使用stringstream进行类型转换操作

    stringstream包括istringstream和ostringstream,提供读写string的功能,使用时需包含stream文件.4个操作:1. stringstream strm; 创建 ...

  10. P - Atlantis - hdu1542(求面积)

    题意:rt 求面积......不计算重复面积(废话..)hdu1255 的弱化版,应该先做这道题在做那道题的. ******************************************** ...