Asp.Net SignalR 使用记录 技术回炉重造-总纲 动态类型dynamic转换为特定类型T的方案 通过对象方法获取委托_C#反射获取委托_ .net core入门-跨域访问配置...

Asp.Net SignalR 使用记录

 

工作上遇到一个推送消息的功能的实现。本着面向百度编程的思想。网上百度了一大堆。主要的实现方式是原生的WebSocket,和SignalR,再次写一个关于Asp.Net SignalR 的demo 

这里简单的介绍一下Signalr,SignalR 封装了WebSocket、ForeverFrame、ServerSentEvents、LongPolling四种主要的传输协议。兼容性比较好,WebSocket 是有要求的,IIS服务需要系统是Win8或者 Server 2012 以上。下面开始撸代码。

1.首先建立一个项目。

Asp.Net SignalR 使用记录 技术回炉重造-总纲 动态类型dynamic转换为特定类型T的方案 通过对象方法获取委托_C#反射获取委托_ .net core入门-跨域访问配置..._第1张图片

2.通过包管理工具,引入SignalR 

Asp.Net SignalR 使用记录 技术回炉重造-总纲 动态类型dynamic转换为特定类型T的方案 通过对象方法获取委托_C#反射获取委托_ .net core入门-跨域访问配置..._第2张图片

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类

 Asp.Net SignalR 使用记录 技术回炉重造-总纲 动态类型dynamic转换为特定类型T的方案 通过对象方法获取委托_C#反射获取委托_ .net core入门-跨域访问配置..._第3张图片

 

    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 Action Action { get; set; }
            /// 
            /// 实例方法委托(实例类型+定义委托参数)
            /// 
            public Action Action2 { get; set; }
        }
    复制代码

     

    2-初始化类:

    创建委托方法1--创建静态方法的委托,只需要2个参数:委托类型和方法信息:

    Delegate.CreateDelegate(typeof(Action), myTipType.GetMethod("SendTipsToDingding"))

     

    创建委托方法2--创建实例方法的委托,需要2+1个参数:除了上面的委托类型和方法信息;还有,,,还有被委托方法对应的实例类型!!!

    即:Action 类型必须改为含有实例类型的委托: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

     

     

     

    转载于:https://www.cnblogs.com/cjm123/p/11250969.html

    你可能感兴趣的:(c#,json,网络)