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



上一章,我们已经初步讲解了微信公众账号开发的基本原理,今天我们来探索设计实现。

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

主要功能介绍如下:

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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目录: 第1章 微信生态 1.1 微信:是一个生活方式 1 1.2 微信公众平台 6 1.2.1 公众平台简介 6 1.2.2 服务和订阅 7 1.3 企业 8 1.4 小程序 8 1.5 微信开放平台 9 1.6 微信支付 10 1.7 表情开放平台 12 1.8 微信广告 12 1.9 小结 13 第2章 开发环境及技术介绍 2.1 集成软件包介绍 14 2.2 XAMPP的安装与配置 15 2.3 PhpStorm的安装及配置 20 2.4 相关技术介绍 23 2.4.1 HTTP 23 2.4.2 HTML5 25 2.5 小结 26 第3章 开发前的准备 3.1 开发概述 27 3.1.1 OpenID 27 3.1.2 公众使用场景 28 3.2 公众消息会话流程 30 3.3 接入指南 31 3.4 接口权限及调用频率 33 3.5 微信网页开发样式库 35 3.6 小结 37 第4章 常用调试方法及工具 4.1 微信测试 38 4.2 接口在线调试 41 4.3 微信Web开发者工具 42 4.3.1 微信网页授权调试 43 4.3.2 JS-SDK权限校验 45 4.3.3 网页远程调试 45 4.4 前端调试工具 46 4.4.1 谷歌浏览器开发者工具 48 4.5 移动端抓包与调试 50 4.5.1 Charles抓包工具 55 4.6 小结 56 第5章 基于CodeIgniter的微信公众平台开发框架 5.1 CodeIgniter简介 57 5.2 工程代码改造 59 5.3 微信公众开发配置 60 5.4 小结 63 第6章 微信网页开发 6.1 微信网页授权原理 64 6.1.1 网页授权注意事项 65 6.1.2 网页授权流程 66 6.2 微信网页授权实例 67 6.3 微信网页多域名授权 74 6.3.1 原理分析 74 6.3.2 代码实现 76 6.4 微信JS-SDK 78 6.4.1 接入准备 79 6.4.2 JS-SDK接口实例 80 6.5 小结 85 第7章 微信支付 7.1 微信支付接入方式 86 7.2 微信支付准备工作 88 7.3 微信支付实践 89 7.3.1 示例代码解析 90 7.3.2 支付示例 91 7.3.3 支付结果通知 96 7.4 聚合支付 99 7.4.1 聚合支付接入示例 101 7.5 小结 105 第8章 微信登录 8.1 微信开放平台 107 8.1.1 UnionID机制 108 8.2 微信自动登录 109 8.2.1 数据结构设计 110 8.2.2 代码实现 112 8.2.3 使用UnionID登录 117 8.2.4 如何应用到现有站点 118 8.3 小结 120 第9章 微信小程序 9.1 小程序简介 121 9.2 开发环境及框架 122 9.2.1 开发配置 125 9.2.2 HTTPS配置 126 9.3.1 iOS/Android开发者 129 9.3 如何着手开发小程序 129 9.4 页面生命周期 130 9.3.2 前端开发者 130 9.3.3 后端开发者 130 9.5 小程序组件和API 134 9.6 小程序登录 134 9.7 小程序微信支付 140 9.8 小结 145 第10章 案例:第一个echo server程序 10.1 接入开发者模式 146 10.2 消息响应 147 10.2.1 公众会话保存Session 153 10.3 自定义菜单 154 10.4 小结 157 第11章 案例:微信随手记 11.1 需求描述 159 11.2 数据库设计 159 11.3 代码实现 161 11.3.1 添加主题 161 11.3.3 主题查看 163 11.3.4 图片下载 166 11.3.5 图片预览 169 11.3.6 聊天机器人 170 11.3.7 入口函数 174 11.4 运行效果 175 11.5 小结 177

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值