Senparc.Weixin.Sample.MP源码剖析

  Senparc.Weixin.Sample.MP是微信公众号样例的.NET6源码,项目配置文件appsettings.json的修改和微信公众号测试环境的搭建参考:微信公众号调试与Natapp环境搭建。接下来从项目结构,项目应用和项目源码3个角度来进行讲解。

一.项目结构角度

项目代码整体结构如下所示:425449ea8c658ea590a52f7e5eea88c9.png重点部分是MessageHandlers消息处理器部分,包括消息上下文、消息处理器和事件处理器。项目启动起来后的界面为:194adecd940750941818ac0905a7c06b.png

二.应用角度

1.数据流的直观过程

首先要明白微信客户端、微信服务器和第三方网站这3者之间的数据流关系,下面通过用户发送文字为例介绍数据流的过程:

  • 用户通过微信客户端发送OpenId

  • 微信服务器就把该文字发送给第三方网站。当然如果没有第三方网站,就是说没有对公众号做二次开发,那么用户得不到任何回应消息

  • 第三方网站对消息进行处理,比如获取该用户的OpenId等相关信息

  • 第三方网站把处理后的消息返回给微信服务器

  • 微信服务器转发第三方网站的消息给微信客户端

  • 这样用户就收到了微信客户端回应的消息318993c2a46845299a816973d59e69ab.png微信的消息类型主要包括请求消息和响应消息,请求消息就是微信服务器发送给网站的消息,而响应消息就是网站发送给微信服务器的消息。具体请求消息和响应消息包含的类型如下所示:6c05e338de0514152ad608b0ce899860.png

2.数据流的代码过程

(1)公众号消息模拟器
公众号消息模拟器输入和输出内容如下所示:13d4024dde301ef40fc4f9283fcb1596.png

  • URL:通过Natapp映射的域名,即http://fengling.nat300.top -> 127.0.0.1:8080。

  • Token、AppId和AESKey:参考appsettings.json文件。

  • 类型:文本、地理位置、图片、语音、视频、时间推送。

  • 内容:OPENID。文本消息处理器对文本进行处理。

(2)Post(PostModel postModel)方法
用户发送消息后,微信平台自动Post一个请求到方法public async TaskPost(PostModel postModel),并等待响应XML:617c2742bbfcf7f7e31f1c071a99e1bb.png在这个方法中通过自定义MessageHandler进行处理:

var messageHandler = new CustomMessageHandler(await Request.GetRequestMemoryStreamAsync(), postModel, maxRecordCount);

真正的微信处理过程方法是:

public async Task ExecuteAsync(CancellationToken cancellationToken)

(3)OnTextRequestAsync(RequestMessageText requestMessage)方法
5d8ed0befad556f1c93389c35f678139.png该方法可以根据输入文本进行响应,可以是匹配关键字、正则表达式、不回复,或者默认响应。

三.源码角度

1.Program.cs代码

首先介绍下Senparc.Weixin SDK整体注册的相关代码:

// 使用本地缓存必须添加
builder.Services.AddMemoryCache();
// Senparc.Weixin 注册(必须)
builder.Services.AddSenparcWeixinServices(builder.Configuration);
...
var senparcWeixinSetting = app.Services.GetService<IOptions<SenparcWeixinSetting>>()!.Value;
//启用微信配置(必须)
var registerService = app.UseSenparcWeixin(app.Environment,null /*不为null则覆盖appsettings中的SenpacSetting配置*/,null /*不为null则覆盖appsettings中的SenpacWeixinSetting配置*/,register => { /*CO2NET全局配置*/ },(register, weixinSetting) =>{//注册公众号信息(可以执行多次,注册多个公众号)register.RegisterMpAccount(weixinSetting, "XXX公众号");});  
......
// 使用公众号的MessageHandler中间件(不再需要创建Controller)  
app.UseMessageHandlerForMp("/WeixinAsync", CustomMessageHandler.GenerateMessageHandler, options =>
{options.AccountSettingFunc = context => Senparc.Weixin.Config.SenparcWeixinSetting;
});

(1)builder.Services.AddMemoryCache()
框架支持内存缓存、Redis、Memcached等多种缓存策略。
(2)builder.Services.AddSenparcWeixinServices(builder.Configuration)
实现Senparc.Weixin的注册。
(3)app.UseSenparcWeixin()
该方法集成了CON2ET全局注册以及Senparc.Weixin SDK微信注册过程。
(4)app.UseMessageHandlerForMp
使用MessageHandler配置,会默认使用异步方法messageHandler.ExecuteAsync()。

2.WeixinController.cs代码

(1)public ActionResult Get(PostModel postModel, string echostr)
该方法主要用于微信后台地址验证,其它的时候用不到。
(2)public async Task<ActionResult> Post(PostModel postModel)
这个方法就是微信服务器转发消息[XML]给网站,等待网站处理后返回消息[XML]给微信服务器的过程。
(3)messageHandler.OmitRepeatedMessage = true;

  • 当网站不能及时响应微信服务器的请求时,微信服务器会连续发送多条相同MsgId的消息到网站,以防止丢包。这种情况就需要利用MsgId对消息进行去重,否则网站就会多次执行同一个请求。

  • 需要注意的是,对于多条带有相同MsgId的请求消息进行多次回复,客户端也只能收到微信服务器最后一次重发所对应的这条响应消息。

(4)messageHandler.DefaultMessageHandlerAsyncEvent = DefaultMessageHandlerAsyncEvent.SelfSynicMethod;
当同步方法被重写,且异步方法未被重写时,尝试调用同步方法。

3.CustomMessageContext.cs代码

(1)CustomMessageContext
CustomMessageContext是消息的上下文,写法基本固定,直接搬过来就可以使用了。消息上下文用于记录单个用户发送、接收消息的记录,就算不同微信公众号同时发送不同的消息,两者之间并不会有任何的干扰,因为两者的上下文是完全隔离的。
(2)CustomMessageContext_MessageContextRemoved
当上下文过期,被移除时触发的时间。根据WeixinContext中的算法,这里的过期消息会在过期后下一条请求执行之前被清除。

4.CustomMessageHandler.cs代码

CustomMessageHandler和CustomMessageHandler_Events是CustomMessageHandler类的2个部分类,前者处理非事件类型的消息,比如发送文本、图像等,而后者处理事件类型的消息,比如点击事件、订阅事件(订阅及取消订阅)等。af2378d3abad265632d8a13424f1c192.png这里的请求消息都是普通消息:638fe63d598a32cc2c3c74b9471e628a.png

5.CustomMessageHandler_Events.cs代码

7e6730179d780e31391b95c574378f6c.png这里的请求消息都是事件推送消息,而事件推送消息又分为3大类型:常规事件[公众号基础功能返回事件],菜单事件[各种类型的公众号菜单返回事件],应用事件[应用模块返回事件]:53e996440ca9fe372ecbbfa3e929ba6a.png

参考文献:
[1]Senparc.Weixin.Sample.MP.sln:WeiXinMPSDK\Samples\MP\Senparc.Weixin.Sample.MP.sln
[2]Senparc.Weixin SDK源码:https://github.com/JeffreySu/WeiXinMPSDK
[3]Senparc.Weixin.MP SDK微信公众平台开发教程(二十三):在.NET Core 2.0/3.0中使用MessageHandler中间件:https://www.cnblogs.com/szw/p/Wechat-MessageHandler-Middleware.html
[4]微信开发深度解析:公众号、小程序高效开发秘籍:http://book.weixin.senparc.com/BookHelper
[5]微信公众平台接口调试工具:https://mp.weixin.qq.com/debug

人工智能干货推荐661186ce9a7467fc3035342b763f4c7c.jpeg专注于人工智能领域的技术分享

游戏元宇宙ef4a78a964cd66266ba99865e01b85d3.jpeg专注于游戏领域的技术分享

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/284333.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mock.js使用

一、Mock.js入门 1&#xff0e; 什么是mock.js? Mock.js &#xff08;官网http://mockjs.com/&#xff09;是一款模拟数据生成器&#xff0c;旨在帮助前端攻城狮独立 于后端进行开发&#xff0c;帮助编写单元测试。提供了以下模拟功能&#xff1a; 1,根据数据模板生成模拟数据…

【ArcGIS微课1000例】0042:ArcGIS自带取色器工具的妙用

在ArcGIS中作图时,通常要进行颜色对照填充,输入特定的RGB值,本文介绍ArcGIS自带取色器工具的妙用,及第三方颜色拾取工具。 文章目录 一、ArcGIS自带取色器二、第三方取色器工具一、ArcGIS自带取色器 很多人可能不知道,ArcGIS中自带取色器工具,如下图所示。 当然了,自带…

微信.NET SDK-Senparc资料整理

微信生态系统包括微信公众号、小程序、微信支付、微信开放平台、企业微信、小游戏等&#xff0c;官方提供了很多的API接口。Senparc是目前使用最广泛的微信.NET SDK&#xff0c;同时支持支持.NET Framework 4.5/.NET Core 2.x/.NET Core 3.x/.NET 5/.NET 6。由于在微信生态开发…

7 种提升 Spring Boot 吞吐量神技

目录 二、增加内嵌Tomcat的最大连接数 三、使用ComponentScan()定位扫包比SpringBootApplication扫包更快 四、默认tomcat容器改为Undertow&#xff08;Jboss下的服务器&#xff0c;Tomcat吞吐量5000&#xff0c;Undertow吞吐量8000&#xff09; 五、使用 BufferedWriter 进…

【ArcGIS微课1000例】0043:ArcGIS缩略图的创建及应用

缩略图通常出现在地图文档中&#xff0c;便于在启动页面中快速打开指定的地图文档&#xff0c;提高效率。 文章目录一、缩略图预览二、缩略图创建一、缩略图预览 打开ArcMap软件&#xff0c;弹出启动窗口&#xff0c;在最近打开的文档中&#xff0c;可以看到两类&#xff0c;一…

JSP简单登录系统

Login登陆界面 <body> 登陆 <% session.invalidate();%> <form action"TestPW.jsp" method"post">用户名<input type"text" name"username"> 密码<input type"password" name"password&quo…

手动从0搭建ABP框架-ABP官方完整解决方案和手动搭建简化解决方案实践

本文主要讲解了如何把ABP官方的在线生成解决方案运行起来&#xff0c;并说明了解决方案中项目间的依赖关系。然后手动实践了如何从0搭建了一个简化的解决方案。ABP官方的在线生成解决方案源码下载参考[3]&#xff0c;手动搭建的简化的解决方案源码下载参考[4]。一.ABP官方在线生…

Java捕获并处理线程失败抛出的异常

使用 UncaughtExceptionHandler 示例代码如下&#xff1a; Thread.UncaughtExceptionHandler handler new Thread.UncaughtExceptionHandler() { public void uncaughtException(Thread th, Throwable ex) {System.out.println("Uncaught exception: " ex);} }; Th…

【ArcGIS微课1000例】0044:ArcGIS使用山体阴影显示DEM的3种方法

本文讲解了ArcGIS使用山体阴影显示DEM的3种方法:“影像分析”窗口、使用山体阴影效果和山体阴影效果工具的不同之处。 文章目录 一、“影像分析”窗口二、使用山体阴影效果三、山体阴影工具一、“影像分析”窗口 使用山体阴影显示 DEM 的方法有两种。最简单并且最具交互效果的…

区块链每日投资指南(0129)-证监会副主席表示数字货币需要监管

上一周的走势依然是工作日下跌&#xff0c;周末拉升的结局。这主要原因依然是&#xff0c;周末不上班。最终政策出炉之前&#xff0c;市场恐怕还将继续震荡。下周的工作日恐怕会重演下跌的节奏。但是经过了17号&#xff0c;23号&#xff0c;26号三次筑底来看&#xff0c;如果政…

蓝绿发布、滚动发布、灰度发布,有什么区别?

在项目迭代的过程中&#xff0c;不可避免需要”上线“。上线对应着部署&#xff0c;或者重新部署&#xff1b;部署对应着修改&#xff1b;修改则意味着风险。目前有很多部署发布的技术, 这儿将常见的做一个总结。 上面所说难免有些抽象, 举一个情景例子, 加入你是微博项目负责…

【ArcGIS微课1000例】0045:ArcGIS制图模板的自定义与使用方法

怎样在ArcGIS中保存地图模板以在地图制图与打印之前使用呢? 文章目录 一、地图模板简介二、地图模板创建1. 创建模板2. 创建缩略图3. 保存模板三、地图模板使用一、地图模板简介 使用ArcMap打开一个已有的地图模板,【文件】→【新建】,任选一个模板,这里选择一个传统模板。…

怎么样的框架对于开发者是友好的?

云原生离.NET开发到底有多远&#xff1f;云原生的概念由来不久&#xff0c;故事从“上云”开始&#xff0c;伴随dorker、k8s等技术的推出&#xff0c;以及CNCF与各大云厂商的共同加持&#xff0c;云原生逐渐被大家所熟知。云原生不依赖具体的云&#xff0c;不管公有云还是私有云…

JS 烧脑面试题大赏

本文精选了20多道具有一定迷惑性的js题&#xff0c;主要考察的是类型判断、作用域、this指向、原型、事件循环等知识点&#xff0c;每道题都配有详细傻瓜式的解析&#xff0c;偏向于初学者&#xff0c;大佬请随意。 第1题 let a 1 function b(a) {a 2console.log(a) } b(a)…

Thinkphp 验证码、文件上传

一、验证码 验证码参数 例题&#xff1a;登录时验证下验证码 LoginController.class.php <?php namespace Home\Controller; use Think\Controller; class LoginController extends Controller {public function Login(){if(empty($_POST)){$this->display(); } e…

ArcGIS实验教程——实验四十七:数据驱动页工具批量制作甘肃省各地级市人口七普专题图集

本实验详细讲解利用ArcGIS数据驱动页工具,制作甘肃省各地级市人口七普专题图集。 文章目录 1. 数据驱动页工具简介2. 甘肃省各地级市人口七普专题图集2.1 符号化及标注2.2 数据驱动页的创建2.3 数据驱动页面文本操作2.4 数据驱动页的导出1. 数据驱动页工具简介 数据驱动页面是…

为什么Java有GC调优而没听说过有CLR的GC调优?

前言在很多的场合我都遇到过一些群友提这样的一些问题&#xff1a;为什么Java有GC调优而CLR没有听说过有GC调优呢&#xff1f;到底是Java的JVM GC比较强还是C#使用的.NET CLR的GC比较强呢&#xff1f;其实业内已经有几位大佬的高赞文章和大家分享一下&#xff0c;主要讨论JVM和…

Ubuntu16.04 - 安装RabbitVCS,linux下的TortoiseSVN!!!

RabbitVCS 官网&#xff1a;http://rabbitvcs.org/ 1&#xff0c;添加PPA源。在shell里面执行下面命令&#xff1a; sudo add-apt-repository ppa:rabbitvcs/ppa 这个命令执行完毕后&#xff0c;查看执行结果看是否密钥导入成功&#xff0c;成功截图&#xff1a; 如果导入密钥失…

【ArcGIS微课1000例】0047:制图表达(2)---河流渐变效果的实现

当我们在ArcMap中加载河流数据时,得到的效果往往如图所示,仅仅是表示河流位置的线要素,既无法真实地反映河流的实际情况,同时在出图的时候也远没有任何美化效果。 文章目录 1.创建制图表达2.添加几何效果3.使用制图规则4.使用制图表达属性覆盖警告:这些操作会对您的数据库…

1 句代码,搞定 ASP.NET Core 绑定多个源到同一个类

问题有群友希望将路由中的信息绑定到一个Dto对象中&#xff1a;public class DDDDDto {[FromRoute(Name "collectionId")]public Guid collectionId { get; set; }[BindProperty(Name "relativeUrl")]public string relativeUrl { get; set; } }这样就不用…