




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、C#微信公眾號(hào)開發(fā)之接收事件推送與消息排重的方法這篇文章主要介紹了C#微信公眾號(hào)開發(fā)之接收事件推送與消息排重的方法,詳細(xì)分析了事件推送與消息排重的使用技巧,對(duì)微信開發(fā)有一定參考借鑒價(jià)值,需要的朋友可以參考下本文實(shí)例講述了C#微信公眾號(hào)開發(fā)之接收事件推送與消息排重的方法。分享給大家供大家參考。具體分析如下: 微信服務(wù)器在5秒內(nèi)收不到響應(yīng)會(huì)斷掉連接,并且重新發(fā)起請(qǐng)求,總共重試三次。這樣的話,問題就來了。有這樣一個(gè)場(chǎng)景:當(dāng)用戶關(guān)注微信賬號(hào)時(shí),獲取當(dāng)前用戶信息,然后將信息寫到數(shù)據(jù)庫中。類似于pc端網(wǎng)站的注冊(cè)。可能由于這個(gè)關(guān)注事件中,我們需要處理的業(yè)務(wù)邏輯比較復(fù)雜。如送積分啊,寫用戶日志啊,分配用戶組啊
2、。等等一系列的邏輯需要執(zhí)行,或者網(wǎng)絡(luò)環(huán)境比較復(fù)雜,無法保證5秒內(nèi)響應(yīng)當(dāng)前用戶的操作,那如果當(dāng)操作尚未完成,微信服務(wù)器又給我們的服務(wù)器推送了一條相同的關(guān)注事件,我們將再次執(zhí)行我們的那些邏輯,這樣就有可能導(dǎo)致數(shù)據(jù)庫中出現(xiàn)重復(fù)的數(shù)據(jù)(有的童鞋就會(huì)說了,我在插入數(shù)據(jù)之前先判斷當(dāng)前是否已經(jīng)存在了,如果存在了就不執(zhí)行插入的操作。我想說的是,我當(dāng)初也是這樣想的,但真實(shí)的運(yùn)行環(huán)境和我們的調(diào)試環(huán)境還是有差距的,直到發(fā)現(xiàn)數(shù)據(jù)庫中有不少重復(fù)的用戶信息時(shí),我才發(fā)現(xiàn)消息去重的重要性。)。 消息的去重普通消息和事件消息是有區(qū)別的。普通消息使用msgid,而事件消息使用FromUserName + CreateTime。我
3、的思路是: 新建類BaseMsg,有三個(gè)屬性分別是FromUser,MsgFlag,CreateTime。代碼如下: 復(fù)制代碼 代碼如下:public class BaseMsg / <summary> / 發(fā)送者標(biāo)識(shí) / </summary> public string FromUser get; set; / <summary> / 消息表示。普通消息時(shí),為msgid,事件消息時(shí),為事件的創(chuàng)建時(shí)間 / </summary> public string MsgFlag get; set; / <summary> / 添加到隊(duì)列的時(shí)間
4、 / </summary> public DateTime CreateTime get; set; 創(chuàng)建個(gè)靜態(tài)列表_queue,用來存儲(chǔ)消息列表,列表的類型是List<BaseMsg>. 在處理微信消息體前,首先判斷列表是否實(shí)例化,如果沒有實(shí)例化則實(shí)例化,否則判斷列表的長(zhǎng)度是否大于或等于50(這個(gè)可以自定義,用處就是微信并發(fā)的消息量),如果大于或等于50,則保留20秒內(nèi)未響應(yīng)的消息(5秒重試一次,總共重試3次,就是15秒,保險(xiǎn)起見這里寫20秒)。 獲取當(dāng)前消息體的消息類型,并根據(jù)_queue判斷當(dāng)前消息是否已經(jīng)請(qǐng)求了。如果是事件則保存FromUser和創(chuàng)建時(shí)間。如果是
5、普通消息則保存MsgFlag。下面是代碼: 復(fù)制代碼 代碼如下:if (_queue = null) _queue = new List<BaseMsg>(); else if(_queue.Count>=50) _queue = _queue.Where(q => return q.CreateTime.AddSeconds(20) > DateTime.Now; ).ToList();/保留20秒內(nèi)未響應(yīng)的消息 XElement xdoc = XElement.Parse(xml); var msgtype = xdoc.Element("MsgTy
6、pe").Value.ToUpper(); var FromUserName = xdoc.Element("FromUserName").Value; var MsgId = xdoc.Element("MsgId").Value; var CreateTime = xdoc.Element("CreateTime").Value; MsgType type = (MsgType)Enum.Parse(typeof(MsgType), msgtype); if (type!=MsgType.EVENT) if (_queu
7、e.FirstOrDefault(m => return m.MsgFlag = MsgId; ) = null) _queue.Add(new BaseMsg CreateTime = DateTime.Now, FromUser = FromUserName, MsgFlag = MsgId ); else return null; else if (_queue.FirstOrDefault(m => return m.MsgFlag = CreateTime; ) = null) _queue.Add(new BaseMsg CreateTime = DateTime.No
8、w, FromUser = FromUserName, MsgFlag = CreateTime ); else return null; 當(dāng)消息已經(jīng)存在隊(duì)列中時(shí),則不轉(zhuǎn)換當(dāng)前的消息為實(shí)體了,直接返回null,調(diào)用的時(shí)候,當(dāng)返回null時(shí)就不做任何處理。 下面開始講解事件消息。接上篇講。所有的消息都繼承BaseMessage,而所有的事件類型都包含一個(gè)Event的屬性。這里為了方便調(diào)用,將消息 復(fù)制代碼 代碼如下:/ <summary> / 事件類型枚舉 / </summary> public enum Event / <summary> / 非事件類型 /
9、 </summary> NOEVENT, / <summary> / 訂閱 / </summary> SUBSCRIBE, / <summary> / 取消訂閱 / </summary> UNSUBSCRIBE, / <summary> / 掃描帶參數(shù)的二維碼 / </summary> SCAN, / <summary> / 地理位置 / </summary> LOCATION, / <summary> / 單擊按鈕 / </summary> CLICK, / &
10、lt;summary> / 鏈接按鈕 / </summary> VIEW, / <summary> / 掃碼推事件 / </summary> SCANCODE_PUSH, / <summary> / 掃碼推事件且彈出“消息接收中”提示框 / </summary> SCANCODE_WAITMSG, / <summary> / 彈出系統(tǒng)拍照發(fā)圖 / </summary> PIC_SYSPHOTO, / <summary> / 彈出拍照或者相冊(cè)發(fā)圖 / </summary> PIC_P
11、HOTO_OR_ALBUM, / <summary> / 彈出微信相冊(cè)發(fā)圖器 / </summary> PIC_WEIXIN, / <summary> / 彈出地理位置選擇器 / </summary> LOCATION_SELECT, / <summary> / 模板消息推送 / </summary> TEMPLATESENDJOBFINISH 定義好枚舉后,就是定義消息實(shí)體了。 關(guān)注/取消關(guān)注事件 xml數(shù)據(jù)包如下: 復(fù)制代碼 代碼如下:<xml> <ToUserName><!CDATAto
12、User></ToUserName> <FromUserName><!CDATAFromUser></FromUserName> <CreateTime>123456789</CreateTime> <MsgType><!CDATAevent></MsgType> <Event><!CDATAsubscribe></Event> </xml> 對(duì)應(yīng)的實(shí)體: 復(fù)制代碼 代碼如下:/ <summary> / 訂閱/取消訂閱事件
13、 / </summary> public class SubEventMessage : EventMessage private string _eventkey; / <summary> / 事件KEY值,qrscene_為前綴,后面為二維碼的參數(shù)值(已去掉前綴,可以直接使用) / </summary> public string EventKey get return _eventkey; set _eventkey = value.Replace("qrscene_", ""); / <summary&g
14、t; / 二維碼的ticket,可用來換取二維碼圖片 / </summary> public string Ticket get; set; 這里需要注意的是,當(dāng)用戶掃描帶參數(shù)的二維碼時(shí),如果用戶沒有關(guān)注當(dāng)前公眾號(hào),用戶關(guān)注時(shí),會(huì)在消息體中帶上qrscene_參數(shù),和Ticket,所以這里定義了兩個(gè)屬性:EventKey,Ticket。當(dāng)給EventKey賦值時(shí),替換掉qrscene_,因?yàn)槲覀冋嬲枰木褪呛竺娴膮?shù)。 掃描帶參數(shù)二維碼事件 用戶掃描帶場(chǎng)景值二維碼時(shí),可能推送一下兩種事件: 如果用戶還未關(guān)注公眾號(hào),則用戶可以關(guān)注公眾號(hào),關(guān)注后微信會(huì)將帶場(chǎng)景值關(guān)注事件推送給開發(fā)者。
15、 如果用戶已經(jīng)關(guān)注公眾號(hào),則微信會(huì)將帶場(chǎng)景值掃描事件推送給開發(fā)者。、 第一種上面已經(jīng)講了,這里就只說明下第二種。 用戶已關(guān)注時(shí)的事件推送 xml包如下: 復(fù)制代碼 代碼如下:<xml> <ToUserName><!CDATAtoUser></ToUserName> <FromUserName><!CDATAFromUser></FromUserName> <CreateTime>123456789</CreateTime> <MsgType><!CDATAevent&g
16、t;</MsgType> <Event><!CDATASCAN></Event> <EventKey><!CDATASCENE_VALUE></EventKey> <Ticket><!CDATATICKET></Ticket> </xml> 對(duì)應(yīng)的實(shí)體如下: 復(fù)制代碼 代碼如下:/ <summary> / 掃描帶參數(shù)的二維碼實(shí)體 / </summary> public class ScanEventMessage : EventMessag
17、e / <summary> / 事件KEY值,是一個(gè)32位無符號(hào)整數(shù),即創(chuàng)建二維碼時(shí)的二維碼scene_id / </summary> public string EventKey get; set; / <summary> / 二維碼的ticket,可用來換取二維碼圖片 / </summary> public string Ticket get; set; 上報(bào)地理位置事件 當(dāng)公眾號(hào)開啟上報(bào)地理位置功能后,每次進(jìn)入公眾號(hào)會(huì)話時(shí),用戶同意上報(bào)地理位置后,都會(huì)在進(jìn)入時(shí)上報(bào)地理位置,或在進(jìn)入回話后每5秒上報(bào)一次地理位置,公眾號(hào)可以再公眾平臺(tái)的后臺(tái)中修
18、改設(shè)置。上報(bào)地理位置時(shí),微信會(huì)將上報(bào)地理位置事件推送到開發(fā)者填寫的url。 xml數(shù)據(jù)包如下: 復(fù)制代碼 代碼如下:<xml> <ToUserName><!CDATAtoUser></ToUserName> <FromUserName><!CDATAfromUser></FromUserName> <CreateTime>123456789</CreateTime> <MsgType><!CDATAevent></MsgType> <Event&
19、gt;<!CDATALOCATION></Event> <Latitude>23.137466</Latitude> <Longitude>113.352425</Longitude> <Precision>119.385040</Precision> </xml> 對(duì)應(yīng)的實(shí)體如下: 復(fù)制代碼 代碼如下:/ <summary> / 上報(bào)地理位置實(shí)體 / </summary> public class LocationEventMessage : EventMess
20、age / <summary> / 地理位置緯度 / </summary> public string Latitude get; set; / <summary> / 地理位置經(jīng)度 / </summary> public string Longitude get; set; / <summary> / 地理位置精度 / </summary> public string Precision get; set; 自定義菜單事件常用的事件有:click,view,scancode_puth,scancode_waitmsg,l
21、ocation_select。另外還有三種發(fā)圖的事件,由于并不常用,筆者也沒想到使用場(chǎng)景,再次就不一一講述了,有興趣的可以自己研究下,或者和我進(jìn)行交流。 click事件推送的xml數(shù)據(jù)包: 復(fù)制代碼 代碼如下:<xml> <ToUserName><!CDATAtoUser></ToUserName> <FromUserName><!CDATAFromUser></FromUserName> <CreateTime>123456789</CreateTime> <MsgType>
22、;<!CDATAevent></MsgType> <Event><!CDATACLICK></Event> <EventKey><!CDATAEVENTKEY></EventKey> </xml> view事件推送的xml數(shù)據(jù)包和click的格式是一樣的,所以定義一個(gè)類就可以了,如下: 復(fù)制代碼 代碼如下:/ <summary> / 普通菜單事件,包括click和view / </summary> public class NormalMenuEventMessa
23、ge : EventMessage / <summary> / 事件KEY值,設(shè)置的跳轉(zhuǎn)URL / </summary> public string EventKey get; set; scancode事件的xml數(shù)據(jù)包如下: 復(fù)制代碼 代碼如下:<xml><ToUserName><!CDATAToUserName></ToUserName> <FromUserName><!CDATAFromUserName></FromUserName> <CreateTime>1419
24、265698</CreateTime> <MsgType><!CDATAevent></MsgType> <Event><!CDATAscancode_push></Event> <EventKey><!CDATAEventKey></EventKey> <ScanCodeInfo><ScanType><!CDATAqrcode></ScanType> <ScanResult><!CDATA </Scan
25、CodeInfo> </xml> 對(duì)應(yīng)的實(shí)體如下: 復(fù)制代碼 代碼如下:/ <summary> / 菜單掃描事件 / </summary> public class ScanMenuEventMessage : EventMessage / <summary> / 事件KEY值 / </summary> public string EventKey get; set; / <summary> / 掃碼類型。qrcode是二維碼,其他的是條碼 / </summary> public string ScanT
26、ype get; set; / <summary> / 掃描結(jié)果 / </summary> public string ScanResult get; set; 至此,當(dāng)前常用的事件類型消息都已定義完畢,結(jié)合上一篇所講的,將xml數(shù)據(jù)包轉(zhuǎn)換成對(duì)象的完整代碼如下: 復(fù)制代碼 代碼如下:public class MessageFactory private static List<BaseMsg> _queue; public static BaseMessage CreateMessage(string xml) if (_queue = null) _que
27、ue = new List<BaseMsg>(); else if(_queue.Count>=50) _queue = _queue.Where(q => return q.CreateTime.AddSeconds(20) > DateTime.Now; ).ToList();/保留20秒內(nèi)未響應(yīng)的消息 XElement xdoc = XElement.Parse(xml); var msgtype = xdoc.Element("MsgType").Value.ToUpper(); var FromUserName = xdoc.Elem
28、ent("FromUserName").Value; var MsgId = xdoc.Element("MsgId").Value; var CreateTime = xdoc.Element("CreateTime").Value; MsgType type = (MsgType)Enum.Parse(typeof(MsgType), msgtype); if (type!=MsgType.EVENT) if (_queue.FirstOrDefault(m => return m.MsgFlag = MsgId; ) =
29、null) _queue.Add(new BaseMsg CreateTime = DateTime.Now, FromUser = FromUserName, MsgFlag = MsgId ); else return null; else if (_queue.FirstOrDefault(m => return m.MsgFlag = CreateTime; ) = null) _queue.Add(new BaseMsg CreateTime = DateTime.Now, FromUser = FromUserName, MsgFlag = CreateTime ); els
30、e return null; switch (type) case MsgType.TEXT: return Utils.ConvertObj<TextMessage>(xml); case MsgType.IMAGE: return Utils.ConvertObj<ImgMessage>(xml); case MsgType.VIDEO: return Utils.ConvertObj<VideoMessage>(xml); case MsgType.VOICE: return Utils.ConvertObj<VoiceMessage>(xml); case MsgType.LINK: return Utils.ConvertO
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 浙江省杭州八中2025屆高三下學(xué)期期末學(xué)習(xí)能力診斷數(shù)學(xué)試題含解析
- 吉林省白城市洮南十中2024-2025學(xué)年高三第五次教學(xué)質(zhì)量檢測(cè)試題考試數(shù)學(xué)試題含解析
- 新疆維吾爾自治區(qū)2025年初三下學(xué)期第四次月考英語試題含答案
- 統(tǒng)編版二年級(jí)語文下冊(cè)期末測(cè)試卷(D)(含答案)
- 部編版2024-2025學(xué)年五下語文期中模擬卷(1-4)(有答案)
- 收割機(jī)操作員勞務(wù)合同
- 工程承包合同稅務(wù)處理框架協(xié)議
- 合同履行擔(dān)保制度探索與實(shí)踐
- 中醫(yī)內(nèi)科學(xué)與中醫(yī)臨證方法課件
- 3《這是我們的校園》公開課一等獎(jiǎng)創(chuàng)新教學(xué)設(shè)計(jì)(表格式)-1
- “皖南八校”2024-2025學(xué)年高一第二學(xué)期期中考試-生物(乙)及答案
- 血站安全與衛(wèi)生培訓(xùn)課件
- 巖土真實(shí)考試題及答案
- 2024年全國(guó)中學(xué)生生物學(xué)聯(lián)賽試題含答案
- 數(shù)獨(dú)題目高級(jí)50題(后附答案)
- 全媒體運(yùn)營(yíng)師-國(guó)家職業(yè)標(biāo)準(zhǔn)(2023年版)
- 2023年浙江高職考數(shù)學(xué)真題卷
- 深圳市失業(yè)人員停止領(lǐng)取失業(yè)保險(xiǎn)待遇申請(qǐng)表樣表
- JIS G4305-2021 冷軋不銹鋼板材、薄板材和帶材
- 附件:湖北省重點(diǎn)水利水電工程施工招標(biāo)投標(biāo)評(píng)分標(biāo)準(zhǔn)-鄂水
- 充填灌漿試驗(yàn)施工方案
評(píng)論
0/150
提交評(píng)論