Im vorherigen Kapitel haben wir zunächst die Grundprinzipien der Entwicklung öffentlicher WeChat-Konten erläutert. Heute werden wir die Designimplementierung untersuchen.
Zunächst haben wir ein Modulhierarchiediagramm entworfen. Das Diagramm zeigt natürlich nur eine Implementierungsmethode und ist nicht darauf beschränkt. Einzelheiten finden Sie in der Abbildung unten.
Die Hauptfunktionen werden wie folgt eingeführt:
1) Anforderungsschnittstellenschicht. Verarbeitung von HTTP-Anfragen und -Antworten
2) Verteilungsschicht. Die Anfrage wird von der Schnittstellenschicht übergeben, und dann wird der Anfragetyp spezifisch analysiert und an verschiedene Prozessoren verteilt
3) Geschäftslogikschicht. Hier ist unsere spezifische Geschäftslogik. Je nach Anforderung wird die spezifische Geschäftslogik implementiert.
4) Datenschicht. Wenn wir eine Anwendung implementieren, müssen wir möglicherweise auf Daten zugreifen, bei denen es sich um eine Datenbank oder eine Datei handeln kann. Wenn es sich um eine einfache Anwendung handelt, ist diese Ebene möglicherweise nicht verfügbar.
Tatsächlich können bestimmte Anwendungen auf dieser Struktur erweitert werden, und die Nachrichtenobjektschicht, die Geschäftsobjektschicht, die Datenzugriffsschicht, die Funktionsverwaltungsschicht usw. können erweitert werden. Dies dient lediglich der Veranschaulichung und ist nicht darauf beschränkt.
Entwerfen Sie ein Flussdiagramm basierend auf dem hierarchischen Diagramm und beschreiben Sie jeden Implementierungsprozess im Detail. den gesamten Prozess zu verstehen. Wie in der folgenden Abbildung dargestellt:
Anhand des Flussdiagramms können wir den gesamten Prozess und die spezifischen Implementierungsschritte der Nachrichtenverarbeitung klar verstehen.
Nachfolgend implementieren wir den Code für jeden Prozess.
Wir benötigen einen HttpHandler oder eine Webseite, um HTTP-Anfragen des WeChat-Servers zu verarbeiten.
Hier verwenden wir HttpHandler. Aufgrund seiner hohen Flexibilität und guten Leistung.
Die spezifische Implementierung ist wie folgt.
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(); } }
Wenn es sich um HTTPHandler handelt, müssen Sie die spezifische Anwendung in der Konfigurationsdatei konfigurieren. Wir werden die spezifische Knotenkonfiguration nicht erklären. Geben Sie direkt ein Beispiel und konfigurieren Sie den HttpHandler-Knoten wie folgt: Verteilungsanforderung
Um die Funktion zu kapseln, kapseln wir diese auch in der Verarbeitungskomponente. Tatsächlich kann es in HttpHandler platziert werden.
1) Signatur überprüfen
<httpHandlers> <add verb="*" path="WXService.ashx" type="namespace.WeiXinHttpHandler,WXWeb" validate="true"/></httpHandlers>
Geschäftslogik:
Verschlüsselungs-/Verifizierungsprozess: <1> Fügen Sie die drei Parameter Token, Zeitstempel und Nonce in das Wörterbuch ein Reihenfolge sortieren<2> Fügen Sie die drei Parameterzeichenfolgen zu einer Zeichenfolge für die SHA1-Verschlüsselung zusammen <3> Der Entwickler kann die verschlüsselte Zeichenfolge mit der Signatur vergleichen, um zu identifizieren, von wem die Anfrage stammt WeChat und die offiziell bereitgestellten PHP-Codebeispiele sind nicht direkt in C# übersetzt. Daher gibt es auch hier einige spezifische Behandlungen. Schauen wir uns zunächst den offiziellen Code an: Wir übersetzen ihn in die C#-Version:Hier ist eine SHA1-Verschlüsselung erforderlich. Der spezifische Algorithmus lautet wie folgt:
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; } }
2) Verteilungsanfrage
/// <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; } }
Der nächste Schritt ist die spezifische Nachrichtenanfrage, hier sind alle POST-Anfragen.
Da es mehrere Nachrichtentypen gibt, kapseln wir sie durch Fabrikklassen, und dann verfügt jede Nachricht über einen eigenen Prozessor für die Verarbeitung. Spezifische Implementierungslogik:
/// <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(); }
Externe Methode zur Verarbeitung von Anforderungen (dies ist die von HttpHandler aufgerufene Methode), das heißt:
/// <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. Nachrichtenprozessor verarbeitet speziell Nachrichten
1) Nachrichtentyp
Zuerst Werfen wir einen Blick auf die spezifischen Nachrichtentypen. Tatsächlich wurde die Nachrichtenschnittstelle im vorherigen Bild klar dargestellt.
/// <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 "无法处理"; } }
这里给出类图,供参考。
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中文网!