年底了,比較忙,大家都在展望未來,對於30+的我來說,發展和穩定是個難以取舍的問題。最近發了些求職信,鳥無音訊,沒事做,做點幫助大家的東西吧。
之前做了個微信公眾平台的查詢系統,在開發中,發覺了一些微信公眾平台的接口問題《對微信公眾平台開發的消息處理》,開發起來比較痛苦,對於微信過來的消息,需要解析后一個一個來返回,編寫之痛苦,相信有人明白。在開發中,一直考慮着如何來簡化開發,暫時想不到好的模式來開發,就自己胡亂寫了一個,希望對大家有幫助。
代碼已發布到github:https://github.com/JamesYing/JCWX
第一步:創建Model類庫,我把微信發送來的消息,事件、返回回去的消息,都寫成了Demo
RequestMessage:微信發送過來的消息、事件。此類是個虛類,繼承自WXMessage。
ResponseMessage:返回給微信服務器端的消息,同樣也是虛類,繼承自WXMessage。
在《對微信公眾平台開發的消息處理》中,已經知道,微信服務器端通過Post方式,發來一段xml,通過Request.InputStream獲取,是個Stream類型,之前一直考慮着,用XmlSerializer.Deserialize(stream)來解析成對象,但在實踐當中,發覺無法判斷MsgType,我必須先判斷再解析,從性能上來說不太合適,所以我又重寫了RequestMessage的構造函數,RequestMessage(XElement),把Stream –> XElement,就可以構造RequestMessage(要使用.net framework 3.5以上版本,您也可以自己修改成適合3.5以下版本)。不過我還是保留了原先的Deserialize方式,使用方法:RequestMessage.Deserializ<RequestMessage>(stream),具體可以參考我的源代碼。
我們知道返回給用戶的也是一個Xml信息,您可以直接使用ResponseMessage.Serializable()返回給用戶xml文檔。ResponseMessage的構造函數中,有一個ResponseMessage(RequestMessage message),這是為了把FromUserName, ToUserName轉換一下,后續文章會繼續講解。
第二步:創建了Business類庫,提供一些公開接口,方便大家來進行開發。
IMessageRole:信息處理規則,規則的具體實現,請繼承此接口
IMessageHandler:信息處理,根據信息,反饋給用戶。
NotHandlerMessage:繼承自IMessageHandler,這是一個在無法處理情況下,返回一個null的實現,您也可以自己來寫。
IMessageRole接口中,只有一個IMessageHandler MessageRole(XElement xml);方法,為了提高性能,我把過來的Stream轉換成了XElement,通過xml.Element(“MsgType”)進行類型判斷,返回一個IMessageHandler。
IMEssageHandler:ResponseMessage HandlerRequestMessage(XElement xml);根據不同的Request返回給用戶不同的ResponseMessage。
這個快速框架就這些,很簡單,實踐的話,需要自己編寫:
1、信息處理規則,繼承IMessageRole,在處理中,您可以根據MsgType進行分析,也可以根據不同Text內容進行分析,返回不同IMessageHanlder就可以了。
2、信息處理,繼承IMessageHandler,這個可能要寫很多個,看你的項目要求了。
微信公眾平台提供了測試接口,但暫時我還沒有用,就簡單自己模擬了下。
創建一個RequestTextMessage(文本信息):
var request = new RequestTextMessage { ToUserName = "sh_bus", FromUserName = "jamesying1", MsgId = 123123123L, CreateTime = 1231231322L, Content = "my request message" };
模擬成Stream:
StringWriter sw = new StringWriter(); var xmlSerializer = new XmlSerializer(typeof(RequestTextMessage)); var ns = new XmlSerializerNamespaces(); ns.Add("", ""); xmlSerializer.Serialize(sw, request, ns); Console.WriteLine(sw.ToString()); Stream stream = new MemoryStream(sw.Encoding.GetBytes(sw.ToString()));
好了,有了模擬環境,我們,我們寫一個自己的規則:
public class MyMessageRole : IMessageRole { public IMessageHandler MessageRole(XElement xml) { try { MsgType msgType = (MsgType)Enum.Parse(typeof(MsgType), xml.Element("MsgType").Value, true); return MessageHandlerByMsgType(msgType); } catch { return new NotHandlerMessage(); } } private IMessageHandler MessageHandlerByMsgType(MsgType msgType) { IMessageHandler messageHandler = null; switch (msgType) { case MsgType.Text: messageHandler = new TextMessageHander(); break; case MsgType.Event: messageHandler = new EventMessageHandler(); break; default: messageHandler = new NotHandlerMessage(); break; } return messageHandler; } }
再編寫2個消息處理類:
public class TextMessageHandler : IMessageHandler { public ResponseMessage HandlerRequestMessage(XElement xml) { var request = new RequestTextMessage(xml); if (request.Content.IndexOf("info") > -1) { return new ResponseTextMessage(request) { Content = "this message has keyword:info" }; } else { return new ResponseTextMessage(request) { Content = "this message has not keyword" }; } } }
TextMessageHandler中,處理的類型為文本信息,判斷內容中含有info,返回一個ResponseTextMessage。下面我們實踐下:
var reader = XmlReader.Create(stream); var doc = XDocument.Load(reader); var xml = doc.Element("xml"); IMessageRole role = new MyMessageRole(); IMessageHandler handler = role.MessageRole(xml); ResponseMessage response = handler.HandlerRequestMessage(xml); if (response != null) { Console.WriteLine(response.Serializable()); } else { Console.WriteLine("not handler"); }
請加入response的判斷,檢查是否為空,因為我們不是每條消息都必須處理的。
看下運行結果:
ok,運行成功,目前還未進行測試,后續會加入測試代碼,相信有了這個快速開發框架,會給大家開發微信公眾平台有更好的幫助。好了,下班了,明天繼續說明一些Model。
代碼已發布到github:https://github.com/JamesYing/JCWX