SignalR系列续集[系列6:使用自己的连接ID]

原文:SignalR系列续集[系列6:使用自己的连接ID]

目录

SignalR系列目录

前言

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

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

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

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

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

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

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

 

 

代码环境

开发工具:VS2013   数据库:SQL2008 R2   SignalR版本:2.2

 

 

正文开始

其实在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的替换工作.

 

 

写在最后

SignalR确实是一个很好用的东西,无奈国内资料确实很少,有问题可以向我反馈,我会尽量在国外的站上找相关的资料整理成博客,希望SignalR发展的越来越好!

时间: 2024-09-15 03:51:39

SignalR系列续集[系列6:使用自己的连接ID]的相关文章

[渣译文] SignalR 2.0 系列: SignalR 自托管主机

原文:[渣译文] SignalR 2.0 系列: SignalR 自托管主机 英文渣水平,大伙凑合着看吧-- 这是微软官方SignalR 2.0教程Getting Started with ASP.NET SignalR 2.0系列的翻译,这里是第六篇: SignalR 自托管主机 原文:SignalR Self-Host PS.前面的那篇在MVC5上使用SignalR跳过了--MVC5跟HTML的实现完全一样,只是将HTML的脚本放在View里面了,这里就跳过了.有兴趣的同学可以自己去看. 概

[渣译文] SignalR 2.0 系列: SignalR简介

原文:[渣译文] SignalR 2.0 系列: SignalR简介 英文渣水平,大伙凑合着看吧,并不是逐字翻译的-- 这是微软官方SignalR 2.0教程Getting Started with ASP.NET SignalR 2.0系列的翻译,这里是第一篇:SignalR简介 原文: Introduction to SignalR 什么是SignalR? ASP.NET SignalR是为简化开发开发人员将实时web内容添加到应用程序过程而提供的类库.实时web功能指的是让服务器代码可以随

[渣译文] SignalR 2.0 系列: 开始使用SignalR 2.0

原文:[渣译文] SignalR 2.0 系列: 开始使用SignalR 2.0 英文渣水平,大伙凑合着看吧-- 这是微软官方SignalR 2.0教程Getting Started with ASP.NET SignalR 2.0系列的翻译,这里是第四篇:开始使用SignalR 2.0 原文:Getting Started with SignalR 2.0 PS.前面的那篇从SignalR1.0升级为2.0跳过了--只有几步,有兴趣的同学可以自己去看. 概述 本教程展示了如何使用SignalR

[渣译文] SignalR 2.0 系列: 支持的平台

原文:[渣译文] SignalR 2.0 系列: 支持的平台 英文渣水平,大伙凑合着看吧,并不是逐字翻译的-- 这是微软官方SignalR 2.0教程Getting Started with ASP.NET SignalR 2.0系列的翻译,这里是第二篇:支持的平台 原文:Supported Platforms SignalR支持多种服务器和客户端配置.此外,每种传输方式都有自身的要求限制:如果某种传输方式不被系统支持,SignalR能够优雅地将故障转移到其他类型的传输方式.关于SignalR所

IT软件的编程方向 - 进阶者系列 - 学习者系列文章

         IT软件经过了这么些年的发展,已经形成了很多的软件公司和开发团队,而且当前编程语言也有很多种,让开发人员能够有很大的选择.现在国际上的开发阵营基本分为ASP.NET.JAVA和PHP三种,但是每种开发语言能够进行的开发问题是统一的,本文就从IT软件的编程方向出发,介绍下当前主流的开发方向.   一.网站: 现在的互联网,随着电子商务的发展和企业内部办公系统的应用,以及编程语言的三大阵营的发展,已经形成了很多具体应用的网站系统.但是,在企业内部,很多还是使用ASP.NET和JAV

编写Javascript类库(jQuery版) - 进阶者系列 - 学习者系列文章

      这些年主要关注于项目管理方面的工作,编码就比较少了.这几天比较空闲,就想把原来的经验沉淀下来,一个是做好记录,以后如果忘记了还能尽快找回来,第二个是写写博文,算是练练手笔吧.       言归正传,这次写的是Javascript类库.大家都知道,Javacript是一种很有意思的语言.虽然它是前端语言,但是它能做的事情远远超出我们的想象.Javascript同样是一种面向对象的语言,使用它,同样可以自定义对象,同样也具备对象的一些特性,即封装,继承,多态性.同时,Javascript

Windows操作系统优化(Win7版) - 进阶者系列 - 学习者系列文章

Windows系统优化是个永恒的话题.在操作系统的打包制作方面更是有得一拼.前面提到的龙帝国社区的XP系统就是一个典型的例子,打包好的系统就已经是经过优化的,使用者无需再使用优化工具进行处理.下面就对Windows7系统的一些优化做一点建议吧.   1.  在桌面的我的电脑上鼠标右键,选择属性.     2.  下面选择高级系统设置.     3.  选择高级选项卡,选择设置.     4.  去掉自动管理分页大小选项.并选择无分页文件,点击设置.     5.  选择启动和故障恢复,选择设置.

安装免费的正版Windows10操作系统 - 初学者系列 - 学习者系列文章

Windows 10操作系统是目前Windows平台最新的操作系统,其相对于其它旧版的操作系统是一个比较成功的操作系统.微软直接使用10版本号,跳过了9版本号进行发布这款操作系统,说明windows 10操作系统还是有一定的改进和用户体验的. 但是,windows 10操作系统既能够通过光盘进行安装,也能过通过U盘进行安装.今天讲的是如果通过工具安装正版的windows 10操作系统.(使用Vmware虚拟机)   一.下载获取正版windows 10的工具. 首先,我们要使用这个工具(http

用SignalR 2.0开发客服系统[系列2:实现聊天室]

原文:用SignalR 2.0开发客服系统[系列2:实现聊天室] 前言 上周发表了 用SignalR 2.0开发客服系统[系列1:实现群发通讯] 这篇文章,得到了很多帮助和鼓励,小弟在此真心的感谢大家的支持.. 这周继续系列2,实现聊天室的功能.     开发环境  开发工具:VS2013 旗舰版  数据库:未用  操作系统:WIN7旗舰版   正文开始 首先我们来看看最终效果:       正式开始: SignalR作为一个强大的集线器,已经在hub里面集成了Gorups,也就是分组管理,使用