經過前面章節的學習,咱們已經對微信的開發有了基本的掌握與熟悉,基本能夠上手作複雜的應用了。本篇咱們將詳細講解微信消息管理中普通消息的接收與處理。當普通微信用戶向公衆帳號發消息時,微信服務器將POST消息的XML數據包到開發者填寫的URL上。接收普通消息微信官方文檔參考:接收普通消息文檔API
消息接收後,就有一個處理或回覆的過程,單單發送消息了沒有響應也是不人性化的,下面咱們就對接收到微信各種型消息分別講解處理的方法。git
當普通微信用戶向公衆帳號發消息時,微信服務器會先接收到用戶發送的消息,而後將用戶消息按照指定的XML格式組裝好數據,最後POST消息的XML數據包到開發者填寫的URL上。github
接收到的普通消息的消息類型目前有如下幾種:服務器
每一種消息類型都有其指定的XML數據格式,這7種消息的xml格式請到官方文檔查看,有具體的格式定義和屬性說明。格式很簡單,基本共有屬性包括ToUserName、FromUserName、CreateTime、MsgType、MsgId,而且每種類型有本身特殊的屬性。微信
接收消息的過程其實就是獲取post請求的這個xml,而後對這個xml進行分析的過程。post請求的入口仍是以前提到的微信公衆號接入的那個地址,整個公衆號的全部請求都會走這個入口,只是接入時是get請求,其它狀況下是post請求。微信公衆平臺
微信服務器在將用戶的消息發給公衆號的開發者服務器地址後,會等待開發者服務器回覆響應消息。微信服務器在五秒內收不到響應會斷掉鏈接,而且從新發起請求,總共重試三次。框架
假如服務器沒法保證在五秒內處理並回復,必須作出下述回覆,這樣微信服務器纔不會對此做任何處理,而且不會發起重試(這種狀況下,可使用客服消息接口進行異步回覆),不然,將出現嚴重的錯誤提示。詳見下面說明:異步
一、(推薦方式)直接回復success分佈式
二、直接回復空串(指字節長度爲0的空字符串,而不是XML結構體中content字段的內容爲空)ide
一旦遇到如下狀況,微信都會在公衆號會話中,向用戶下發系統提示「該公衆號暫時沒法提供服務,請稍後再試」:post
一、開發者在5秒內未回覆任何內容
二、開發者回覆了異常數據,好比JSON數據等
另外,請注意,回覆圖片等多媒體消息時須要預先經過素材管理接口上傳臨時素材到微信服務器,可使用素材管理中的臨時素材,也可使用永久素材。
消息回覆目前支持回覆文本、圖片、圖文、語音、視頻、音樂,每一種類型的消息都有特定的XML數據格式。這幾種回覆消息的xml數據格式請參考官方文檔,有具體的格式定義和屬性說明。格式很簡單,基本共有屬性包括ToUserName、FromUserName、CreateTime、MsgType,而且每種類型有本身特殊的屬性。
使用Senparc.Weixin框架來快速處理各類接收的普通消息,實現很是簡單,自定義一個繼承MessageHandler的類,重寫這7種類型的方法便可。注意:DefaultResponseMessage必須重寫,用於返回沒有處理過的消息類型(也能夠用於默認消息,如幫助信息等);其中全部原OnXX的抽象方法已經都改成虛方法,能夠沒必要每一個都重寫。若不重寫,默認返回DefaultResponseMessage方法中的結果。
CustomMessageHandle.cs須要繼承Senparc.Weixin.MP.MessageHandlers
可能以下:
public class CustomMessageHandler : MessageHandler<CustomMessageContext> { public CustomMessageHandler(Stream inputStream, PostModel postModel) : base(inputStream, postModel) { } public override IResponseMessageBase DefaultResponseMessage(IRequestMessageBase requestMessage) { var responseMessage = base.CreateResponseMessage<ResponseMessageText>(); //ResponseMessageText也能夠是News等其餘類型 responseMessage.Content = "這條消息來自DefaultResponseMessage。"; return responseMessage; } }
咱們能夠看到必需要重寫實現的抽象方法名爲DefaultResponseMessage(),這一條信息用於返回一條的消息,假如對應類型(如語音)的微信消息沒有被代碼處理,那麼默認會返回這裏的結果。在DefaultResponseMessage()方法中,咱們看到這樣一句:
var responseMessage = base.CreateResponseMessage<ResponseMessageText>(); //ResponseMessageText也能夠是News等其餘類型
這裏的CreateResponseMessage
各類類型的消息咱們能夠根據咱們本身的業務要求進行重寫回復,若是沒重寫就會返回默認的消息(重寫默認響應的基礎上)。
文本消息對應的數據包XML格式以下:
<xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[fromUser]]></FromUserName> <CreateTime>1348831860</CreateTime> <MsgType><![CDATA[text]]></MsgType> <Content><![CDATA[this is a test]]></Content> <MsgId>1234567890123456</MsgId> </xml>
參數說明:
參數 描述 ToUserName 開發者微信號(直接把它當作你的公衆號的微信號便可) FromUserName 發送方賬號(一個OpenID) CreateTime 消息建立時間 (整型) MsgType 消息類型,文本爲text Content 文本消息內容 MsgId 消息id,64位整型
處理文本消息參考代碼:
/// <summary> /// 處理文字請求 /// </summary> /// <returns></returns> public override IResponseMessageBase OnTextRequest(RequestMessageText requestMessage) { //注意:下面泛型ResponseMessageText即返回給客戶端的類型,能夠根據本身的須要填寫ResponseMessageNews等不一樣類型。 var responseMessage = CreateResponseMessage<ResponseMessageText>(); var result = new StringBuilder(); result.AppendFormat("您剛發送了文本信息:{0}\r\n\r\n", requestMessage.Content); if (CurrentMessageContext.RequestMessages.Count > 1) { result.AppendFormat("您剛還發送了以下消息({0}/{1}):\r\n", CurrentMessageContext.RequestMessages.Count, CurrentMessageContext.StorageData); for (int i = CurrentMessageContext.RequestMessages.Count - 2; i >= 0; i--) { var historyMessage = CurrentMessageContext.RequestMessages[i]; result.AppendFormat("{0} 【{1}】{2}\r\n", historyMessage.CreateTime.ToShortTimeString(), historyMessage.MsgType.ToString(), (historyMessage is RequestMessageText) ? (historyMessage as RequestMessageText).Content : "[非文字類型]" ); } result.AppendLine("\r\n"); } result.AppendFormat("若是您在{0}分鐘內連續發送消息,記錄將被自動保留(當前設置:最多記錄{1}條)。過時後記錄將會自動清除。\r\n", WeixinContext.ExpireMinutes, WeixinContext.MaxRecordCount); result.AppendLine("\r\n"); result.AppendLine("您還能夠發送【位置】【圖片】【語音】【視頻】等類型的信息(注意是這幾種類型,不是這幾個文字),查看不一樣格式的回覆。"); responseMessage.Content = result.ToString(); return responseMessage; }
圖片消息對應的數據包XML格式以下:
<xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[fromUser]]></FromUserName> <CreateTime>1348831860</CreateTime> <MsgType><![CDATA[image]]></MsgType> <PicUrl><![CDATA[this is a url]]></PicUrl> <MediaId><![CDATA[media_id]]></MediaId> <MsgId>1234567890123456</MsgId> </xml>
參數說明:
參數 描述 ToUserName 開發者微信號 FromUserName 發送方賬號(一個OpenID) CreateTime 消息建立時間 (整型) MsgType 消息類型,圖片爲image PicUrl 圖片連接(由系統生成) MediaId 圖片消息媒體id,能夠調用獲取臨時素材接口拉取數據。 MsgId 消息id,64位整型
處理圖片消息參考代碼:
/// <summary> /// 處理圖片請求 /// </summary> /// <param name="requestMessage"></param> /// <returns></returns> public override IResponseMessageBase OnImageRequest(RequestMessageImage requestMessage) { var responseMessage = CreateResponseMessage<ResponseMessageNews>(); responseMessage.Articles.Add(new Article() { Title = "您剛纔發送了圖片信息", Description = "您發送的圖片將會顯示在邊上", PicUrl = requestMessage.PicUrl, Url = "http://blog.rdiframework.net/" }); responseMessage.Articles.Add(new Article() { Title = "第二條", Description = "第二條帶鏈接的內容", PicUrl = requestMessage.PicUrl, Url = "http://blog.rdiframework.net/" }); return responseMessage; }
在上面代碼中咱們返回了用戶發送的圖片消息,同時加上了連接地址,用戶單擊消息會自動跳轉到指定的URL地址。
語音消息對應的數據包XML格式以下:
<xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[fromUser]]></FromUserName> <CreateTime>1357290913</CreateTime> <MsgType><![CDATA[voice]]></MsgType> <MediaId><![CDATA[media_id]]></MediaId> <Format><![CDATA[Format]]></Format> <MsgId>1234567890123456</MsgId> </xml>
參數 描述 ToUserName 開發者微信號 FromUserName 發送方賬號(一個OpenID) CreateTime 消息建立時間 (整型) MsgType 語音爲voice MediaId 語音消息媒體id,能夠調用獲取臨時素材接口拉取數據。 Format 語音格式,如amr,speex等 MsgID 消息id,64位整型
參數說明:
處理語音消息參考代碼:
/// <summary> /// 處理語音請求 /// </summary> /// <param name="requestMessage"></param> /// <returns></returns> public override IResponseMessageBase OnVoiceRequest(RequestMessageVoice requestMessage) { //得到當前公衆號 WeixinOfficialAccountEntity account = RDIFrameworkService.Instance.WeixinBasicService.GetOfficialAccountEntity(Id); var responseMessage = CreateResponseMessage<ResponseMessageMusic>(); //上傳縮略圖 var uploadResult = Senparc.Weixin.MP.AdvancedAPIs.MediaApi.UploadTemporaryMedia(account.AccessToken, UploadMediaFileType.image,Server.GetMapPath("~/Content/Images/weixing-ma.png")); //設置音樂信息 responseMessage.Music.Title = "天籟之音"; responseMessage.Music.Description = "播放您上傳的語音"; responseMessage.Music.MusicUrl = "http://www.rdiframework.net/resource/25375532.mp3"; responseMessage.Music.HQMusicUrl = "http://www.rdiframework.net/Media/GetVoice?mediaId=" + requestMessage.MediaId; responseMessage.Music.ThumbMediaId = uploadResult.media_id; return responseMessage; }
視頻消息對應的數據包XML格式以下:
<xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[fromUser]]></FromUserName> <CreateTime>1357290913</CreateTime> <MsgType><![CDATA[video]]></MsgType> <MediaId><![CDATA[media_id]]></MediaId> <ThumbMediaId><![CDATA[thumb_media_id]]></ThumbMediaId> <MsgId>1234567890123456</MsgId> </xml>
參數說明:
參數 描述 ToUserName 開發者微信號 FromUserName 發送方賬號(一個OpenID) CreateTime 消息建立時間 (整型) MsgType 視頻爲video MediaId 視頻消息媒體id,能夠調用獲取臨時素材接口拉取數據。 ThumbMediaId 視頻消息縮略圖的媒體id,能夠調用多媒體文件下載接口拉取數據。 MsgId 消息id,64位整型
處理視頻消息參考代碼:
/// <summary> /// 處理視頻請求 /// </summary> /// <param name="requestMessage"></param> /// <returns></returns> public override IResponseMessageBase OnVideoRequest(RequestMessageVideo requestMessage) { var responseMessage = CreateResponseMessage<ResponseMessageText>(); responseMessage.Content = "您發送了一條視頻信息,ID:" + requestMessage.MediaId; return responseMessage; }
視頻與小視頻主要區別是在MsgType上,其餘的都同樣。
小視頻消息對應的數據包XML格式以下:
<xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[fromUser]]></FromUserName> <CreateTime>1357290913</CreateTime> <MsgType><![CDATA[shortvideo]]></MsgType> <MediaId><![CDATA[media_id]]></MediaId> <ThumbMediaId><![CDATA[thumb_media_id]]></ThumbMediaId> <MsgId>1234567890123456</MsgId> </xml>
參數說明:
參數 描述 ToUserName 開發者微信號 FromUserName 發送方賬號(一個OpenID) CreateTime 消息建立時間 (整型) MsgType 小視頻爲shortvideo MediaId 視頻消息媒體id,能夠調用獲取臨時素材接口拉取數據。 ThumbMediaId 視頻消息縮略圖的媒體id,能夠調用獲取臨時素材接口拉取數據。 MsgId 消息id,64位整型
處理小視頻消息參考代碼:
public override IResponseMessageBase OnShortVideoRequest(RequestMessageShortVideo requestMessage) { var responseMessage = this.CreateResponseMessage<ResponseMessageText>(); responseMessage.Content = "您剛纔發送的是小視頻"; return responseMessage; }
地理位置消息對應的數據包XML格式以下:
<xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[fromUser]]></FromUserName> <CreateTime>1351776360</CreateTime> <MsgType><![CDATA[location]]></MsgType> <Location_X>23.134521</Location_X> <Location_Y>113.358803</Location_Y> <Scale>20</Scale> <Label><![CDATA[位置信息]]></Label> <MsgId>1234567890123456</MsgId> </xml>
參數說明:
參數 描述 ToUserName 開發者微信號 FromUserName 發送方賬號(一個OpenID) CreateTime 消息建立時間 (整型) MsgType 消息類型,地理位置爲location Location_X 地理位置維度 Location_Y 地理位置經度 Scale 地圖縮放大小 Label 地理位置信息 MsgId 消息id,64位整型
處理地理位置消息參考代碼:
/// <summary> /// 處理位置請求 /// </summary> /// <param name="requestMessage"></param> /// <returns></returns> public override IResponseMessageBase OnLocationRequest(RequestMessageLocation requestMessage) { //返回的是圖文消息,是關於地址的圖文消息。 var responseLocation = base.CreateResponseMessage<ResponseMessageNews>(); var markersList = new List<BaiduMarkers>(); markersList.Add(new BaiduMarkers() { Size = BaiduMarkerSize.m, Color = "red", Label = "A", Latitude = requestMessage.Location_X, Longitude = requestMessage.Location_Y, }); var mapUrl = BaiduMapHelper.GetBaiduStaticMap(requestMessage.Location_Y, requestMessage.Location_X, 1, 13, markersList); responseLocation.Articles.Add(new Article() { Description = string.Format("您剛纔發送了地理位置信息。Location_X:{0},Location_Y:{1},Scale:{2},標籤:{3}", requestMessage.Location_X, requestMessage.Location_Y, requestMessage.Scale, requestMessage.Label), PicUrl = SystemInfo.WeChatSiteUrl +"/Content/Images/toplogo.png", Title = "國思軟件快速開發框架-地圖返回", Url = mapUrl }); return responseLocation; }
對於回覆的消息,咱們還能夠單擊彈出百度地圖返回的位置詳情,具體應用可據此擴展。
連接消息對應的數據包XML格式以下:
<xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[fromUser]]></FromUserName> <CreateTime>1351776360</CreateTime> <MsgType><![CDATA[link]]></MsgType> <Title><![CDATA[公衆平臺官網連接]]></Title> <Description><![CDATA[公衆平臺官網連接]]></Description> <Url><![CDATA[url]]></Url> <MsgId>1234567890123456</MsgId> </xml>
參數說明:
參數 描述 ToUserName 接收方微信號 FromUserName 發送方微信號,若爲普通用戶,則是一個OpenID CreateTime 消息建立時間 MsgType 消息類型,連接爲link Title 消息標題 Description 消息描述 Url 消息連接 MsgId 消息id,64位整型
連接位置消息參考代碼:
/// <summary> /// 處理連接消息請求 /// </summary> /// <param name="requestMessage"></param> /// <returns></returns> public override IResponseMessageBase OnLinkRequest(RequestMessageLink requestMessage) { var responseMessage = ResponseMessageBase.CreateFromRequestMessage<ResponseMessageText>(requestMessage); responseMessage.Content = string.Format(@"您發送了一條鏈接信息: Title:{0} Description:{1} Url:{2}", requestMessage.Title, requestMessage.Description, requestMessage.Url); return responseMessage; }
RDIFramework.NET — 基於.NET的快速信息化系統開發框架 — 系列目錄
RDIFramework.NET ━ .NET快速信息化系統開發框架 ━ 工做流程組件介紹
RDIFramework.NET框架SOA解決方案(集Windows服務、WinForm形式與IIS形式發佈)-分佈式應用
RDIFramework.NET代碼生成器全新V3.5版本發佈-重大升級
一路走來數個年頭,感謝RDIFramework.NET框架的支持者與使用者,你們能夠經過下面的地址瞭解詳情。
RDIFramework.NET官方網站:http://www.rdiframework.net/
RDIFramework.NET官方博客:http://blog.rdiframework.net/
同時須要說明的,之後的全部技術文章以官方網站爲準,歡迎你們收藏!
RDIFramework.NET框架由專業團隊長期打造、一直在更新、一直在升級,請放心使用!
歡迎關注RDIFramework.net框架官方公衆微信(微信號:guosisoft),及時瞭解最新動態。
掃描二維碼當即關注