Asp.Net SignalR 使用记录
工作上遇到一个推送消息的功能的实现。本着面向百度编程的思想。网上百度了一大堆。主要的实现方式是原生的WebSocket,和SignalR,再次写一个关于Asp.Net SignalR 的demo
这里简单的介绍一下Signalr,SignalR 封装了WebSocket、ForeverFrame、ServerSentEvents、LongPolling四种主要的传输协议。兼容性比较好,WebSocket 是有要求的,IIS服务需要系统是Win8或者 Server 2012 以上。下面开始撸代码。
1.首先建立一个项目。
2.通过包管理工具,引入SignalR
3.引入之后,需要手动添加两个类。
PushHub 集线器类,Singlarl类的主要操作都由这个类实现。
1 public class PushHub : Hub 2 { 3 ///4 /// 第一次连接 5 /// 6 ///7 public override Task OnConnected() 8 { 9 return base.OnConnected(); 10 } 11 12 /// 13 /// 断开连接 14 /// 15 /// 16 ///17 public override Task OnDisconnected(bool stopCalled) 18 { 19 string user = ConnectManager.GetUserName(Context.ConnectionId); 20 ConnectManager.RemoveUser(user); 21 Show(string.Format("{0}退出", user)); 22 23 return base.OnDisconnected(stopCalled); 24 } 25 26 /// 27 /// 获取当前的用户标识 28 /// 29 ///30 private string GetUserId() 31 { 32 return Context.QueryString["userId"]; 33 } 34 35 /// 36 /// 发送消息 37 /// 38 /// 39 /// 40 public void Show(string content,string receiveUser="") 41 { 42 string user = ConnectManager.GetUserName(Context.ConnectionId); 43 if (string.IsNullOrEmpty(receiveUser)) 44 { 45 Clients.All.show(content); 46 } 47 else { 48 Clients.Client(ConnectManager.GetUserConnect(receiveUser)).show(string.Format("{0}发消息:{1}",user, content)); 49 } 50 51 } 52 53 ///54 /// 登录操作 55 /// 56 /// 57 public void Login(string user) 58 { 59 60 ConnectManager.OnlineInit(user, Context.ConnectionId); 61 Show(string.Format("{0}:登录成功", user)); 62 } 63 64 }
4.Startup类
public class Startup { public void Configuration(IAppBuilder app) { app.MapSignalR(); //声明注册集线器映射 } }
5.连接管理类
1 ///2 /// 连接管理类 3 /// 4 public class ConnectManager 5 { 6 ///7 /// 连接记录池 8 /// 9 private readonly static ConcurrentDictionary_connectPool = new ConcurrentDictionary (); 10 11 /// 12 /// 添加用户 13 /// 14 /// 15 /// 16 public static void AddUser(string userKey, string connection) 17 { 18 _connectPool[userKey] = connection; 19 } 20 21 ///22 /// 删除用户 23 /// 24 /// 25 public static void RemoveUser(string userKey) 26 { 27 string connection = null; 28 _connectPool.TryRemove(userKey, out connection); 29 } 30 31 ///32 /// 是否存在连接(是否在线) 33 /// 34 /// 35 ///36 public static bool IsOnline(string receiverId) 37 { 38 return _connectPool.Keys.Contains(receiverId); 39 } 40 41 /// 42 /// 推送消息给个人 43 /// 44 /// 45 /// 46 public static void PushSingleMessage(string receiveId, string msg) 47 { 48 try 49 { 50 GetHubContext().Clients.Client(_connectPool[receiveId]).show(msg); 51 } 52 catch (Exception ex) 53 { 54 var errMsg = ex.Message; 55 } 56 } 57 58 ///59 /// 获取推送上下文 60 /// 61 ///62 public static IHubContext GetHubContext() 63 { 64 return GlobalHost.ConnectionManager.GetHubContext (); 65 } 66 67 /// 68 /// 上线初始化 69 /// 70 /// 用户ID 71 /// 连接ID 72 public static void OnlineInit(string userId, string connectionId) 73 { 74 AddUser(userId, connectionId); 75 } 76 77 public static string GetUserName(string value) 78 { 79 return _connectPool.Where(a => a.Value == value).FirstOrDefault().Key; 80 } 81 82 public static string GetUserConnect(string userName) 83 { 84 return _connectPool[userName]; 85 } 86 }
6.前台代码
用户名称:///这个要注意默认就是这样写,不要问为什么。哈哈
接收人:
接收到的信息:
这就是所有的demo的代码
demo代码:https://github.com/chaorending/Demo.SignalR.git
技术回炉重造-总纲
前言
工作有些年了,总是忙忙碌碌。也用到好些个技术和优秀框架,却不曾深入学习,基础知识又慢慢忘记了,导致现在总感觉空落落的。上个月,经过技术经理的提议及动员,决定部门内部开启每周一次的技术交流会议,大家轮流主持。所以,是时候总结汇总一下了。
正文
.NET平台:
.NET简介;.NET体系结构组件;目标框架;.NET术语表;开放源代码库指南;为服务器应用选择 .NET Core 或 .NET Framework;公共语言运行时 (CLR);.NET 类库;处理和引发异常;垃圾回收;泛型类型;委托和 lambda;LINQ;常规类型系统和公共语言规范;集合和数据结构;.NET中的数字;日期、时间和时区;事件;托管执行过程;元数据和自描述组件;生成控制台应用程序;应用程序要点;文件和流 I/O;全球化和本地化;特性;框架设计准则;XML 文档和数据;安全性;序列化;开发多平台应用程序;
C#语言基础篇:
C#概述;C#环境配置;C#程序结构;C#基本语法;C#数据类型;C#类型转换;C#变量;C#常量和文字;C#运算符;C#判断;C#循环;C#封装;C#方法;C#可空类型;C#数组;C#字符串;C#结构体;C#枚举;C#类;C#继承;C#多态性;C#运算符重载;C#接口;C#命名空间;C#预处理指令;C#正则表达式;C#异常处理;C#文件 I/O
C#语言进阶篇:
C#特性;C#反射;C#属性;C#索引器;C#委托;C#事件;C#集合;C#泛型;C#匿名方法;C#不安全代码;C#多线程
拓展篇:
动态语言拓展;内存管理和指针;错误和异常;程序集;线程 任务和同步 安全性;本地化;事务;网络 windows服务;互操作性;文件和注册表操作;核心ado.net;处理xml;缓存;序列化;编码 过滤器;ICO; DI; AOP; 数据验证;大数据;机器学习;设计模式;
WEB:
Razor;webAPI;MVC;ASP.NET;asp.net Core;Route;
工具&中间件:
Git;Redis Quartz.NET;RabbitMQ;Log4Net;IOC;ORM;Socket;Swagger;
前端篇:
HTML;CSS;javascript;DOM;Json;Ajax;Jquery;Bootstrap;Vue.js;LayUI;node.js;webpack;Chart;
数据库:
mssql;mysql;oracle;mongodb;
动态类型dynamic转换为特定类型T的方案
需求场景:有时候我们抓到一段请求数据,JSON格式的字符串数据,需要放在接口里重现问题,我们就可能会用dynamic先接受数据,然后再转换成特定数据发出请求。
方案一:直接使用特定对象T,来接受请求数据,不可以吗? 当然可以,不过当JSON数据包含子对象时,我遇到了子数据对象丢失的问题。如果你们没有遇到,可以使用。
方案二:使用字符串接受JSON格式的字符串数据,然后反序列化成对象,不过这个你需要对字符串进行处理,加反斜杠,如果你不嫌麻烦,可以使用。
方案三:我个人推荐:使用dynamic类型先接受数据,然后再转换成T对象,比较方便,实用,下面是关键代码:
思路:使用dynamic.ToString()方法,得到Json的字符串,然后使用反序列化方法,可以避免方案一的数据丢失问题。好用!!!推荐!!!
////// 模拟请求 /// /// 接收响应结果为加密之后的值 ///得到解密之后返回的响应结果值 [HttpPost] public HttpResponseMessage Test(dynamic fromBody)//dynamic JObject { string a = fromBody.ToString(); T t= Newtonsoft.Json.JsonConvert.DeserializeObject(a); return result; }
通过对象方法获取委托_C#反射获取委托_
前言:时间紧,先写关键代码,以后优化:
在此感谢其他博友分享的文章,参考文章:C#反射委托创建器
1-定义含有委托的类:
public class TimeCycle { ////// 唯一标识 /// public int ID { get; set; } ////// 静态方法委托(只定义委托参数即可) /// public ActionAction { get; set; } /// /// 实例方法委托(实例类型+定义委托参数) /// public ActionAction2 { get; set; } }
2-初始化类:
创建委托方法1--创建静态方法的委托,只需要2个参数:委托类型和方法信息:
Delegate.CreateDelegate(typeof(Action
创建委托方法2--创建实例方法的委托,需要2+1个参数:除了上面的委托类型和方法信息;还有,,,还有被委托方法对应的实例类型!!!
即:Action
所以,实例方法创建的委托必须得包含实例类型才能正常创建。
备注:创建委托失败常出现的一个错误,需要对委托的是否静态方法和对应参数进行检查:
System.ArgumentException:“无法绑定到目标方法,因其签名或安全透明度与委托类型的签名或安全透明度不兼容。”
public partial class MyTipsService : ServiceBase { public void Test() { Type myTipType = typeof(MyTipsService); //创建静态方法委托1: TimeCycle timeCycle1 = new TimeCycle { ID = 1, Action = (Action)Delegate.CreateDelegate(typeof(Action ), myTipType.GetMethod("MyProjectBugTips")), }; //创建实例方法委托2: TimeCycle timeCycle2 = new TimeCycle { ID = 1, Action2 = (Action )Delegate.CreateDelegate(typeof(Action ), myTipType.GetMethod("SendTipsToDingding")), }; var a = 1; } #region 获取提醒消息 /// /// 每天上下班提醒 /// public void SendTipsToDingding(TimeCycle timeCycle, string typeStr) { } ////// 我的项目BUG的提醒 /// public static void MyProjectBugTips(TimeCycle timeCycle, string typeStr) { } #endregion }
.net core入门-跨域访问配置
Asp.net Core 跨域配置
一般情况WebApi都是跨域请求,没有设置跨域一般会报以下错误
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:48057' is therefore not allowed access.
ASP.net Core 跨域有两种,全局和区域
全局跨域:
打开Startup.cs文件.在ConfigureServices方法中添加以下代码
1.配置跨域处理,允许所有来源:
//配置跨域处理,允许所有来源: services.AddCors(options => options.AddPolicy("自定义的跨域策略名称", p => p.AllowAnyOrigin()) );
2.允许一个或多个具体来源:
//允许一个或多个具体来源: services.AddCors(options => { // Policy 名稱 CorsPolicy 是自訂的,可以自己改 options.AddPolicy("跨域规则的名称", policy => { // 設定允許跨域的來源,有多個的話可以用 `,` 隔開 policy.WithOrigins("http://localhost:3000","http://127.0.0.1") .AllowAnyHeader() .AllowAnyMethod() .AllowCredentials(); }); });
以上两种按需求选择一种即可.
Configure方法中添加以下代码
app.UseCors("自定义的跨域策略名称");//必须位于UserMvc之前
app.UseMvc();
局部跨域第一种用法:
1.ConfigureServices方法不变,删去Configure中的app.UseCors()方法
2.在Controller顶部或者Action方法顶部加上[EnableCors("自定义的跨域策略名称")]特性,例如
[EnableCors("自定义的跨域策略名称")]
[Route("api/[controller]")]
public class ContactController : Controller
以上就可实现指定某个controller或者action跨域
禁止跨域:
禁止跨域在Controller或者Action加上[DisableCors]特性即可禁止跨域
[HttpGet("{id}")] [DisableCors] public string Get(int id) { return "value"; }
参考文章:https://www.cnblogs.com/xiaoliangge/p/7650465.html