微信公众平台开发教程(三)基础框架搭建
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
微信公众平台开发教程(三)基础框架搭建
微信公众平台开发教程(三)基础框架搭建
上⼀章,我们已经初步讲解了微信公众账号开发的基本原理,今天我们来探索设计实现。
⾸先我们设计了模块层次图,当然图中只是给出⼀种实现⽅式,不局限于此。
具体见下图。
主要功能介绍如下:
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 = puteHash(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();。