이전 장에서 처음으로 WeChat 공개 계정 개발의 기본 원칙을 설명했습니다. 오늘은 디자인 구현을 살펴보겠습니다.
우선 모듈 계층 다이어그램을 설계했습니다. 물론 다이어그램은 구현 방법만 보여줄 뿐 이에 국한되지는 않습니다. 자세한 내용은 아래 그림을 참조하세요.
주요 기능을 다음과 같이 소개합니다.
1) 요청 인터페이스 계층. HTTP 요청 및 응답 처리
2) 배포 계층. 요청은 인터페이스 계층에서 전달된 후 요청 유형을 구체적으로 분석하여 다양한 프로세서에 배포합니다
3) 비즈니스 로직 계층. 요청에 따라 특정 비즈니스 로직이 구현됩니다.
4) 데이터 계층. 애플리케이션을 구현할 때 데이터베이스나 파일 등의 데이터에 액세스해야 할 수도 있습니다. 단순한 애플리케이션이라면 이 레이어를 사용하지 못할 수도 있습니다.
실제로 이 구조에서는 특정 애플리케이션을 확장할 수 있으며, 메시지 개체 계층, 비즈니스 개체 계층, 데이터 액세스 계층, 기능 관리 계층 등을 확장할 수 있습니다. 이는 단지 아이디어를 제공하기 위한 것이며 이에 국한되지 않습니다.
계층도를 기반으로 흐름도를 설계하고 각 구현 프로세스를 자세히 설명합니다. 전체 과정을 이해하는 것입니다. 아래 그림과 같이
플로우 차트에 따르면 메시지 처리의 전체 프로세스와 구체적인 구현 단계를 명확하게 이해할 수 있습니다.
아래에서는 각 프로세스에 대한 코드를 구현합니다.
WeChat 서버 HTTP 요청을 처리하려면 HttpHandler 또는 웹페이지가 필요합니다.
여기서는 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 노드를 다음과 같이 구성합니다.
함수를 캡슐화하기 위해 처리 구성 요소에도 이를 캡슐화했습니다. 실제로 HttpHandler에 배치할 수 있습니다.
1) 서명 확인
첫 번째 요청인 경우 서명 확인이 필요합니다. 이는 HTTP 핸드셰이크와 동일합니다. 이전 장에서는 서버 URL과 토큰 값을 설정했는데, 연결이 성공했는지 확인하는 기능입니다.
이 요청은 GET 요청입니다. 다음 구체적인 지침(공식): 비즈니스 로직:
<1> order Sorting
<2> SHA1 암호화를 위해 세 개의 매개변수 문자열을 하나의 문자열로 연결합니다
<3> 개발자는 암호화된 문자열을 서명과 비교하여 요청이 발생한 항목을 식별할 수 있습니다. WeChat
및 공식에서는 PHP 코드 예제만 제공했지만 C#에서는 직접 번역되지 않은 것들이 많습니다. 따라서 여기에는 몇 가지 구체적인 치료법도 있습니다. 먼저 공식 코드를 살펴보겠습니다:
<httpHandlers> <add verb="*" path="WXService.ashx" type="namespace.WeiXinHttpHandler,WXWeb" validate="true"/></httpHandlers>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; } }
여기서 SHA1 암호화가 필요합니다. 구체적인 알고리즘은 다음과 같습니다.
/// <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; } }
2) 배포 요청
다음 단계는 특정 메시지 요청입니다. 여기에 모든 POST 요청이 있습니다.
메시지 유형이 다양하기 때문에 이를 팩토리 클래스를 통해 캡슐화하고 각 메시지에는 처리를 위한 전용 프로세서가 있습니다. 특정 구현 논리:
/// <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(); }
요청 처리를 위한 외부 메서드(HttpHandler가 호출하는 메서드), 즉:
/// <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; }
3. 메시지 프로세서는 메시지를 구체적으로 처리합니다.
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; } }
最后将处理结果返回至最初HttpHandler,响应给微信服务器,直接Response处理。这也是在最开始设计的HttpHandler中实现的。
下面是代码片段,具体可见一、Http请求
context.Response.Clear(); context.Response.Charset = "UTF-8"; context.Response.Write(responseMsg); context.Response.End();
更多微信公众平台开发教程(三) 基础框架搭建 相关文章请关注PHP中文网!