微信公众平台开发教程(三) 基础框架搭建

作者:停留的风 时间:2022-08-12 00:33:50 

首先我们设计了模块层次图,当然图中只是给出一种实现方式,不局限于此。具体见下图。

主要功能介绍如下:

1)请求接口层。处理HTTP请求,及响应

2)分发层。由接口层传入请求,然后具体分析请求类型,分发至不同的处理器

3)业务逻辑层。这里是我们的具体业务逻辑了,根据请求,实现具体的业务逻辑。

4)数据层。我们在实现某个应用时可能需要访问数据,可以是数据库或者是文件。如果是简单应用,可能没有这一层。

其实,具体的应用可以在这个结构上去扩展,可以扩展消息对象层、业务对象层、数据访问层、功能管理层等。这里只是提供一种思路,不局限于此。

微信公众平台开发教程(三) 基础框架搭建

根据层次图,设计流程图,具体讲述实现的各个过程。以便了解整个处理过程。如下图所示:

微信公众平台开发教程(三) 基础框架搭建

根据流程图,我们能够清晰的了解整个流程,消息处理的具体实现步骤。

下面我们针对每个流程进行代码实现。

一、接收HTTP请求

我们需要一个HttpHandler或者一个网页,来处理微信服务端HTTP请求。

这里我们使用了HttpHandler。因为其灵活性高,性能好。

具体实现如下。


public class WeiXinHttpHandler:IHttpHandler
 {
   /// <summary>
   ///
   /// </summary>
   public bool IsReusable
   {
     get { return true; }
   }
   /// <summary>
   /// 处理请求
   /// </summary>
   /// <param name="context"></param>
   public void ProcessRequest(HttpContext context)
   {
     //由微信服务接收请求,具体处理请求
     WeiXinService wxService = new WeiXinService(context.Request);
     string responseMsg = wxService.Response();
     context.Response.Clear();
     context.Response.Charset = "UTF-8";
     context.Response.Write(responseMsg);
     context.Response.End();
   }
 }

如果是HTTPHandler,需要在配置文件中,配置具体的应用。具体的节点配置,我们不作说明。直接给出例子,配置HttpHandler节点如下 


<httpHandlers>
 <add verb="*" path="WXService.ashx" type="namespace.WeiXinHttpHandler,WXWeb" validate="true"/>
</httpHandlers>

二、分发请求

 为了能功能封装,我们也将此封装在了处理组件中。其实可以放置在HttpHandler中的。

 1)验证签名

 如果是首次请求,需要验证签名。就相当于一次HTTP握手。之前在上一章中,设置的服务器URL以及token值,这个功能就是检验是否链接成功。

这个请求是GET请求。以下具体说明(官方):

业务逻辑:

加密/校验流程:

<1> 将token、timestamp、nonce三个参数进行字典序排序

<2> 将三个参数字符串拼接成一个字符串进行SHA1加密

 <3> 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信

而官方只提供了PHP的代码示例,很多东西在C#中并非直译既得。所以这里面也有一些具体处理。先看官方的代码:


private function checkSignature()
 {
   $signature = $_GET["signature"];
   $timestamp = $_GET["timestamp"];
   $nonce = $_GET["nonce"];  

$token = TOKEN;
   $tmpArr = array($token, $timestamp, $nonce);
   sort($tmpArr);
   $tmpStr = implode( $tmpArr );
   $tmpStr = sha1( $tmpStr );

if( $tmpStr == $signature ){
     return true;
   }else{
     return false;
   }
 }

我们将其翻译成C#版本:


/// <summary>
   /// 检查签名
   /// </summary>
   /// <param name="request"></param>
   /// <returns></returns>
   private bool CheckSignature()
   {
     string signature = Request.QueryString[SIGNATURE];
     string timestamp = Request.QueryString[TIMESTAMP];
     string nonce = Request.QueryString[NONCE];

List<string> list = new List<string>();
     list.Add(TOKEN);
     list.Add(timestamp);
     list.Add(nonce);
     //排序
     list.Sort();
     //拼串
     string input = string.Empty;
     foreach (var item in list)
     {
       input += item;
     }
     //加密
     string new_signature = SecurityUtility.SHA1Encrypt(input);
     //验证
     if (new_signature == signature)
     {
       return true;
     }
     else
     {
       return false;
     }
   }

这里需要SHA1加密,具体的算法如下:


/// <summary>
   /// SHA1加密
   /// </summary>
   /// <param name="intput">输入字符串</param>
   /// <returns>加密后的字符串</returns>
   public static string SHA1Encrypt(string intput)
   {
     byte[] StrRes = Encoding.Default.GetBytes(intput);
     HashAlgorithm mySHA = new SHA1CryptoServiceProvider();
     StrRes = mySHA.ComputeHash(StrRes);
     StringBuilder EnText = new StringBuilder();
     foreach (byte Byte in StrRes)
     {
       EnText.AppendFormat("{0:x2}", Byte);
     }
     return EnText.ToString();
   }

2)分发请求

接下来就是具体的消息请求了,这里都是POST请求。

因为有多种消息类型,我们通过工厂类来进行封装,然后每种消息都有专门的处理器来进行处理。具体实现逻辑:


/// <summary>
   /// 处理请求
   /// </summary>
   /// <returns></returns>
   private string ResponseMsg()
   {
     string requestXml = Common.ReadRequest(this.Request);
     IHandler handler = HandlerFactory.CreateHandler(requestXml);
     if (handler != null)
     {
       return handler.HandleRequest();
     }

return string.Empty;
   }

处理请求的对外方法(HttpHandler调用的方法就是这个了),即:


/// <summary>
   /// 处理请求,产生响应
   /// </summary>
   /// <returns></returns>
   public string Response()
   {
     string method = Request.HttpMethod.ToUpper();
     //验证签名
     if (method == "GET")
     {
       if (CheckSignature())
       {
         return Request.QueryString[ECHOSTR];
       }
       else
       {
         return "error";
       }
     }

//处理消息
     if (method == "POST")
     {
       return ResponseMsg();
     }
     else
     {
       return "无法处理";
     }
   }

三、消息处理器具体处理消息

1)消息类型

首先我们来看下,具体的消息类型,其实上一张中已经明确给了消息的接口。

这里再看具体看一下,请求的消息类型有哪些,回复的消息类型有哪些等。

千万要注意,请求的消息是文本类型,回复的消息,不一定也是文本哦,可以是图文、音乐等任意一种可回复的消息。具体见下表所示。

微信公众平台开发教程(三) 基础框架搭建

2)根据具体的消息接口,设计消息类。

这里给出类图,供参考。

微信公众平台开发教程(三) 基础框架搭建

3)针对不同的消息,会有不同的处理器,来看下具体的类图。

微信公众平台开发教程(三) 基础框架搭建

4)具体业务处理

每个handler里面就是可以处理具体请求。输入的什么消息,访问那些数据,调用服务等,都在这里处理。

还是建议大家对具体的业务进行单独封装,在Handler中,只提供调用的接口。

因为随着业务的增加,一个Handler可能要处理很多业务,如果所有的操作逻辑都写在这里,势必影响阅读,也不易于维护与扩展。

5)产生回复消息

在处理完请求后,需要生成回复消息,响应到终端。消息格式,就是我们介绍那些消息类型,但必须是可用于回复的,当前支持的有:文本、图文、音乐等。

一定要明确:回复的消息类型不一定要与请求的消息类型一样,比如,请求是文本,回复的可以是图文、音乐。

产生回复消息的过程,其实,就是特定的消息对象格式化为对应的XML的过程,然后将XML响应至微信服务器。

6)实例

这里以微信用户关注公众账号,然后服务端处理处理事件请求,登记用户,并提示欢迎信息。


class EventHandler : IHandler
 {
   /// <summary>
   /// 请求的xml
   /// </summary>
   private string RequestXml { get; set; }
   /// <summary>
   /// 构造函数
   /// </summary>
   /// <param name="requestXml"></param>
   public EventHandler(string requestXml)
   {
     this.RequestXml = requestXml;
   }
   /// <summary>
   /// 处理请求
   /// </summary>
   /// <returns></returns>
   public string HandleRequest()
   {
     string response = string.Empty;
     EventMessage em = EventMessage.LoadFromXml(RequestXml);
     if (em.Event == EventType.Subscribe)
     {
       //注册用户
       User user = new User();
       user.OpenID = em.FromUserName;
       UserManager.Regester(user);

//回复欢迎消息
       TextMessage tm = new TextMessage();
       tm.ToUserName = em.FromUserName;
       tm.FromUserName = em.ToUserName;
       tm.CreateTime = Common.GetNowTime();
       tm.Content = "欢迎您关注xxx,我是小微。有什么我能帮助您的吗?";
       response = tm.GenerateContent();
     }

return response;
   }
 }

 四、HTTP响应

 最后将处理结果返回至最初HttpHandler,响应给微信服务器,直接Response处理。这也是在最开始设计的HttpHandler中实现的。

下面是代码片段,具体可见一、Http请求     


context.Response.Clear();
context.Response.Charset = "UTF-8";
context.Response.Write(responseMsg);
context.Response.End();

来源:http://www.cnblogs.com/yank/p/3392394.html

标签:微信公众号,框架搭建
0
投稿

猜你喜欢

  • java调用Restful接口的三种方法

    2021-09-07 16:49:04
  • C#仿QQ聊天窗口

    2022-09-30 09:12:39
  • Java中自然排序和比较器排序详解

    2022-09-04 21:04:49
  • SpringBoot集成Swagger构建api文档的操作

    2023-11-03 09:13:51
  • Unity实现场景漫游相机

    2023-06-15 19:08:57
  • mybatis中foreach嵌套if标签方式

    2023-11-20 23:11:05
  • Java开发学习 Eclipse项目有红感叹号解决之道

    2022-10-22 15:29:27
  • C#操作串口通信协议Modbus的常用方法介绍

    2023-01-20 04:06:58
  • 使用springboot logback动态获取application的配置项

    2023-09-03 21:21:41
  • Quartz与Spring集成的两种方法示例

    2022-05-22 05:15:41
  • Java实现一个顺序表的完整代码

    2023-09-21 01:00:59
  • SpringBoot自动装配原理小结

    2023-11-18 16:54:06
  • java反射应用详细介绍

    2022-06-14 04:59:45
  • Java面向对象基础,类,变量,方法

    2023-04-08 13:21:49
  • Java多线程之线程通信生产者消费者模式及等待唤醒机制代码详解

    2022-10-31 11:17:22
  • Spring源码解析 Bean属性填充

    2021-06-28 19:17:16
  • SpringCloud Zuul基本使用方法汇总

    2023-11-14 15:21:54
  • Unity Shader实现描边OutLine效果

    2022-01-13 03:11:13
  • Java的异常体系以及File类构造方法详解

    2021-09-05 20:06:41
  • maven的pom文件与打包详解

    2023-12-24 00:23:51
  • asp之家 软件编程 m.aspxhome.com