好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

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

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

主要功能介绍如下:

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

dy("nrwz");

查看更多关于微信公众平台开发教程(三) 基础框架搭建的详细内容...

  阅读:48次