signalr服务端-基础搭建
signalr 支持 iis托管、winform、windowsservices、wpf 托管 这里我采用winfrom托管
首先画一个这样的窗体
在服务项目通过项目管理包安装signalr类库
安装后 如果客户端是web程序 则将js移动到客户端 编写客户端的时候使用
这次我安装缺少一个 程序集 我在官网下载手动引用上去了
新建一个类 该类用于自定义找到signalr回话的id 默认是随机的一个guid维护。。实现这个类 就可以根据用户id 直接发送给指定用户
/// <summary> /// 自定义维护每个用户会话id的实现类 /// </summary> public class UserIdProvider:IUserIdProvider { public string GetUserId(IRequest request) { return request.QueryString["Uid"]; } }
新建一个signalr启动类。并将自定义维护会话注入
public class Startup { public void Configuration(IAppBuilder app) { //注入signlar自定义维护会话id GlobalHost.DependencyResolver.Register(typeof(IUserIdProvider), () => new UserIdProvider()); app.UseCors(CorsOptions.AllowAll); app.MapSignalR(); } }
新建一个服务器的在线用户信息管理类
/// <summary> /// 在线用户信息管理类 /// </summary> public class User { /// <summary> /// 用户id /// </summary> public string Uid { get; set; } /// <summary> /// 用户名字 /// </summary> public string UName { get; set; } /// <summary> /// 上线时间 /// </summary> public DateTime Date { get; set; } /// <summary> /// 头像 /// </summary> public string HeadPath { get; set; } /// <summary> /// 当前用户所在机构id /// </summary> public string OrganId{ get; set; } /// <summary> /// 当前用户所在部门id /// </summary> public string Depid { get; set; } }
引入redis客户端 消息队列管理以及在线用户管理
编写接口层 如果不使用redis可以切换成其他存储
public interface IDeposit { Task<bool> RemoveKey(string key); Task<bool> SetAsync(string key, object value, TimeSpan? timeOut = null); Task<T> GetAsync<T>(string key); Task<bool> ListLeftPush(string key, object value, TimeSpan? ts = null); Task<bool> ListRightPush(string key, object value, TimeSpan? ts = null); Task<T> ListLeftPop<T>(string key); Task<T> ListRightPop<T>(string key); bool HashSet(string keyA, string keyB, object value); T HashGet<T>(string keyA, string keyB); } }
编写实现层
public class RedisManager:IDeposit { private ConnectionMultiplexer _redis; private object _locker = new object(); public ConnectionMultiplexer Manager { get { if (_redis == null) { lock (_locker) { if (_redis != null) return _redis; _redis = GetManager(); return _redis; } } return _redis; } } public IDatabase DB { get { return Manager.GetDatabase(); } } private ConnectionMultiplexer GetManager() { ConfigurationOptions co = new ConfigurationOptions() { EndPoints = { {ConfigHelper.GetRedisIp, ConfigHelper.GetRedisPort } } }; return ConnectionMultiplexer.Connect(co); } public async Task<bool> RemoveKey(string key) { return await DB.KeyDeleteAsync(key); } public async Task<bool> SetAsync(string key, object value, TimeSpan? timeOut=null) { Type t = value.GetType(); bool isOk; if (t.IsClass && t != typeof(string)) { var str = JsonConvert.SerializeObject(value); isOk = Manager.GetDatabase().StringSet(key, str); } else { isOk = Manager.GetDatabase().StringSet(key,value.ToString()); } //设置key的失效时间 if (isOk && timeOut != null) { DB.KeyExpire(key, timeOut); } return isOk; } public async Task<T> GetAsync<T>(string key) { try { if (DB.KeyExists(key)) { Type t = typeof(T); string str = DB.StringGet(key); if (t.IsClass&&t!=typeof(string)) { return JsonConvert.DeserializeObject<T>(str); } else { return (T)Convert.ChangeType(str, t); } } else { return default(T); } } catch (Exception e) { throw e; } } /// <summary> /// 左侧入队 /// </summary> /// <param name="key"></param> /// <param name="value"></param> /// <param name="ts"></param> /// <returns></returns> public async Task<bool> ListLeftPush(string key,object value,TimeSpan?ts=null) { Type t = value.GetType(); bool isOk; long oldLength = DB.ListLength(key); ; if (t.IsClass && t != typeof(string)) { var str = JsonConvert.SerializeObject(value); length = DB.ListLeftPush(key, str); }else{ length = DB.ListLeftPush(key, value.ToString()); } isOk=oldLength < length; //设置key的失效时间 if (isOk && ts != null) { DB.KeyExpire(key, ts); } return isOk; } //右侧入队 public async Task<bool> ListRightPush(string key, object value, TimeSpan? ts = null) { Type t = value.GetType(); bool isOk; long oldLength = DB.ListLength(key); ; if (t.IsClass && t != typeof(string)) { var str = JsonConvert.SerializeObject(value); length = DB.ListRightPush(key, str); } else { length = DB.ListRightPush(key, value.ToString()); } isOk= oldLength < length; //设置key的失效时间 if (isOk && ts != null) { DB.KeyExpire(key, ts); } return isOk; } /// <summary> /// 左侧出队 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="key"></param> /// <returns></returns> public async Task<T> ListLeftPop<T>(string key) { Type t = typeof(T); if (DB.KeyExists(key)) { var values = DB.ListLeftPop(key); if (t.IsClass && t != typeof(string)) { return JsonConvert.DeserializeObject<T>(values); ; } else { return (T)Convert.ChangeType(values, t); } } else { return default(T); } } /// <summary> /// 右侧出队 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="key"></param> /// <returns></returns> public async Task<T> ListRightPop<T>(string key) { Type t = typeof(T); if (DB.KeyExists(key)) { var values = DB.ListRightPop(key); if (t.IsClass && t != typeof(string)) { return JsonConvert.DeserializeObject<T>(values); ; } else { return (T)Convert.ChangeType(values, t); } } else { return default(T); } } public bool HashSet(string keyA, string keyB, object value) { if (DB == null) return false; var t = value.GetType(); bool isOk; if (t.IsClass && t != typeof(string)) { var str = JsonConvert.SerializeObject(value); isOk= DB.HashSet(keyA, keyB, str); } else { isOk= DB.HashSet(keyA,keyB, value.ToString()); } return isOk; } public T HashGet<T>(string keyA, string keyB) { if (DB == null) return default(T); var t = typeof(T); var values = DB.HashGet(keyA,keyB); if (string.IsNullOrEmpty(values)) return default(T); if (t.IsClass && t != typeof(string)) { return JsonConvert.DeserializeObject<T>(values); ; } else { return (T)Convert.ChangeType(values, t); } } }
编写帮助类
public class DepositHelper { public static IDeposit rm = new RedisManager(); public Task<bool> RemoveKey(string key) { return rm.RemoveKey(key); } public static Task<bool> SetAsync(string key, object value, TimeSpan? timeOut = null) { return rm.SetAsync(key, value, timeOut); } public static Task<T> GetAsync<T>(string key) { return rm.GetAsync<T>(key); } public static Task<bool> ListLeftPush(string key, object value, TimeSpan? ts = null) { return rm.ListLeftPush(key, value, ts); } public static Task<bool> ListRightPush(string key, object value, TimeSpan? ts = null) { return rm.ListRightPush(key, value, ts); } public static Task<T> ListLeftPop<T>(string key) { return rm.ListLeftPop<T>(key); } public static Task<T> ListRightPop<T>(string key) { return rm.ListRightPop<T>(key); } public static bool HashSet(string keyA, string keyB, object value) { return rm.HashSet(keyA, keyB, value); } public static T HashGet<T>(string keyA, string keyB) { return rm.HashGet<T>(keyA, keyB); } }
编写在线用户信息管理类
以后再写了
signalr服务端-基础搭建的更多相关文章
- 记录一次SignalR服务端实现过程
前言:最近手上一个项目需要后端实时推送数据到前端,第一个想到的就是微软的SignalR,由于之前都是平时没事写的Demo,没有用到实际项目中,这次恰好用到了,因此记录下来整个实现过程(网上也有很多类似 ...
- SignalR入门之多平台SignalR服务端
之前创建SignalR服务端是基于Web应用程序而言的.那么能不能把SignalR服务端做成控制台应用程序.Winform或windows服务呢? 答案是肯定的. 之前尽管看起来好像是IIS和ASP. ...
- 创建自托管的SignalR服务端
微软官方例子地址:http://www.asp.net/signalr/overview/deployment/tutorial-signalr-self-host 1.说明: SignalR服务端可 ...
- spring-oauth-server实践:客户端和服务端环境搭建
客户端:http://localhost:8080/spring-oauth-client/index.jsp 服务端:http://localhost:8080/spring-oauth-serve ...
- cocos2d-x开发:服务端基础库封装
元旦前面几天都在忙着面试,随后的几天也就一直在做服务端基础库开发方面的工作.对于服务端开发,是很久之前的事情了.那时候我还在大学读书,一直都是在倒腾服务端开发方面的东西,毕业后参加公司工作就是一直从事 ...
- .net core signalR 服务端强制中断用户连接
.net core signalR 服务端断开连接 { } { } *:first-child { } *:last-child { } { } { } { } { } { } { } { } { } ...
- Node服务端极速搭建 - nvmhome
本文意在让你掌握极速搭建Node服务端(任何Project) $ whoami name: kelvin email: kelvv@outlook.com homepage: www.kelvv.co ...
- Node服务端极速搭建 -- nvmhome
> 本文意在让你掌握极速搭建Node服务端(任何Project) ```$ whoaminame: kelvinemail: kelvv@outlook.comhomepage: www.kel ...
- Android中直播视频技术探究之---视频直播服务端环境搭建(Nginx+RTMP)
一.前言 前面介绍了Android中视频直播中的一个重要类ByteBuffer,不了解的同学可以 点击查看 到这里开始,我们开始动手开发了,因为我们后续肯定是需要直播视频功能,然后把视频推流到服务端, ...
随机推荐
- Hadoop系列教程<一>---Hadoop是什么呢?
Hadoop适合应用于大数据存储和大数据分析的应用,适合于服务器几千台到几万台的集群运行,支持PB级的存储容量.Hadoop典型应用有:搜索.日志处理.推荐系统.数据分析.视频图像分析.数据保存等.但 ...
- nginx 访问目录403
centos7.2默认安装好nginx后,会在/usr/share/nginx/html下作为主目录 但是如果想访问下面的目录会发现没有权限,返回403错误 这时候要注意在/etc/nginx/ngi ...
- sql 判断 函数 存储过程是否存在的方法
下面为您介绍sql下用了判断各种资源是否存在的代码,需要的朋友可以参考下,希望对您学习sql的函数及数据库能够有所帮助.库是否存在if exists(select * from master..sys ...
- WPF中,Combox的SelectedItem属性绑定成功后,未能默认显示上一次选择的结果。
问题描述: Combox中,设定了绑定对象,但是在第一次进入时却没有显示上次选中的项. 1)查看SelectedItem对应绑定的值,也是有的(启动时,读取上次设置的结果,来初始化界面). ...
- 配置tomcat https
生成安全证书 打开命令窗口 Windows键+r,输入cmd 切换当前目录到tomcat的conf目录下 生成证书 红色字体标识的参数按实际需要修改 keytool -genkey -alias to ...
- Blog List
Blog List Spark Spark官方文档 - 中文翻译 Spark快速入门 - Spark 1.6.0 Spark SQL 官方文档-中文翻译 Spark SQL 之 Migration G ...
- static
静态数据成员,用关键字static声明,该类的所有对象维护该成员的同一个拷贝(包括该类派生类的对象,即派生类对象与基类对象共享基类的静态数据成员. 1. Static数据成员必须在类外部定义,且正好定 ...
- markdown简要说明源码
##markdown ###什么是markdown: Markdown是一种可以使用普通文本编辑器编写的标记语言,通过简单的标记语法,它可以使普通文本内容具有一定的格式. Markdown具有 ...
- WPF 自定义雷达图
自定义雷达图表如下: Git下载地址:https://github.com/Kybs0/RadarChartControl 1.创建UserControl,名为“RadarChartControl” ...
- android 发送短信功能
private void sendSMS(String num,String smsBody) { String phoneNum = "smsto:" + num; Uri sm ...