程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C#微信號開辟之吸收事宜推送與新聞排重的辦法

C#微信號開辟之吸收事宜推送與新聞排重的辦法

編輯:C#入門知識

C#微信"號開辟之吸收事宜推送與新聞排重的辦法。本站提示廣大學習愛好者:(C#微信"號開辟之吸收事宜推送與新聞排重的辦法)文章只能為提供參考,不一定能成為您想要的結果。以下是C#微信"號開辟之吸收事宜推送與新聞排重的辦法正文


本文實例講述了C#微信"號開辟之吸收事宜推送與新聞排重的辦法。分享給年夜家供年夜家參考。詳細剖析以下:

微佩服務器在5秒內收不到呼應會斷失落銜接,而且從新提議要求,總共重試三次。如許的話,成績就來了。有如許一個場景:當用戶存眷微信賬號時,獲得以後用戶信息,然後將信息寫到數據庫中。相似於pc端網站的注冊。能夠因為這個存眷事宜中,我們須要處置的營業邏輯比擬龐雜。如送積分啊,寫用戶日記啊,分派用戶組啊。等等……一系列的邏輯須要履行,或許收集情況比擬龐雜,沒法包管5秒內呼應以後用戶的操作,那假如當操作還沒有完成,微佩服務器又給我們的辦事器推送了一條雷同的存眷事宜,我們將再次履行我們的那些邏輯,如許就有能夠招致數據庫中湧現反復的數據(有的童鞋就會說了,我在拔出數據之前先斷定以後能否曾經存在了,假如存在了就不履行拔出的操作。我想說的是,我現在也是如許想的,但真實的運轉情況和我們的調試情況照樣有差距的,直到發明數據庫中有很多反復的用戶信息時,我才發明新聞去重的主要性。)。

 
新聞的去重通俗新聞和事宜新聞是有差別的。通俗新聞應用msgid,而事宜新聞應用FromUserName + CreateTime。我的思緒是:
 
新建類BaseMsg,有三個屬性分離是FromUser,MsgFlag,CreateTime。代碼以下:
public class BaseMsg
{
        /// <summary>
        /// 發送者標識
        /// </summary>
        public string FromUser { get; set; }
        /// <summary>
        /// 新聞表現。通俗新聞時,為msgid,事宜新聞時,為事宜的創立時光
        /// </summary>
        public string MsgFlag { get; set; }
        /// <summary>
        /// 添加到隊列的時光
        /// </summary>
        public DateTime CreateTime { get; set; }
}
 
創立個靜態列表_queue,用來存儲新聞列表,列表的類型是List<BaseMsg>.
在處置微信新聞體前,起首斷定列表能否實例化,假如沒有實例化則實例化,不然斷定列表的長度能否年夜於或等於50(這個可以自界說,用途就是微信並發的新聞量),假如年夜於或等於50,則保存20秒內未呼應的新聞(5秒重試一次,總共重試3次,就是15秒,保險起見這裡寫20秒)。
獲得以後新聞體的新聞類型,並依據_queue斷定以後新聞能否曾經要求了。假如是事宜則保留FromUser和創立時光。假如是通俗新聞則保留MsgFlag。上面是代碼:
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秒內未呼應的新聞
}
XElement xdoc = XElement.Parse(xml);
var msgtype = xdoc.Element("MsgType").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 (_queue.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.Now,
  FromUser = FromUserName,
  MsgFlag = CreateTime
     });
 }
 else
 {
     return null;
 }
}
 
當新聞曾經存在隊列中時,則不轉換以後的新聞為實體了,直接前往null,挪用的時刻,當前往null時就不做任何處置。
 
上面開端講授事宜新聞。接上篇講。一切的新聞都繼續BaseMessage,而一切的事宜類型都包括一個Event的屬性。這裡為了便利挪用,將新聞
/// <summary>
/// 事宜類型列舉
/// </summary>
public enum Event
{
        /// <summary>
        /// 非事宜類型
        /// </summary>
        NOEVENT,
        /// <summary>
        /// 定閱
        /// </summary>
        SUBSCRIBE,
        /// <summary>
        /// 撤消定閱
        /// </summary>
        UNSUBSCRIBE,
        /// <summary>
        /// 掃描帶參數的二維碼
        /// </summary>
        SCAN,
        /// <summary>
        /// 地輿地位
        /// </summary>
        LOCATION,
        /// <summary>
        /// 單擊按鈕
        /// </summary>
        CLICK,
        /// <summary>
        /// 鏈接按鈕
        /// </summary>
        VIEW,
        /// <summary>
        /// 掃碼推事宜
        /// </summary>
        SCANCODE_PUSH,
        /// <summary>
        /// 掃碼推事宜且彈出“新聞吸收中”提醒框
        /// </summary>
        SCANCODE_WAITMSG,
        /// <summary>
        /// 彈出體系攝影發圖
        /// </summary>
        PIC_SYSPHOTO,
        /// <summary>
        /// 彈出攝影或許相冊發圖
        /// </summary>
        PIC_PHOTO_OR_ALBUM,
        /// <summary>
        /// 彈出微信相冊發圖器
        /// </summary>
        PIC_WEIXIN,
        /// <summary>
        /// 彈出地輿地位選擇器
        /// </summary>
        LOCATION_SELECT,
        /// <summary>
        /// 模板新聞推送
        /// </summary>
        TEMPLATESENDJOBFINISH
}
 
界說好列舉後,就是界說新聞實體了。
 
存眷/撤消存眷事宜
xml數據包以下:
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[FromUser]]></FromUserName>
<CreateTime>123456789</CreateTime>
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[subscribe]]></Event>
</xml>
 
對應的實體:
/// <summary>
/// 定閱/撤消定閱事宜
/// </summary>
public class SubEventMessage : EventMessage
{
        private string _eventkey;
        /// <summary>
        /// 事宜KEY值,qrscene_為前綴,前面為二維碼的參數值(已去失落前綴,可以直接應用)
        /// </summary>
        public string EventKey
        {
            get { return _eventkey; }
            set { _eventkey = value.WordStr("qrscene_", ""); }
        }
        /// <summary>
        /// 二維碼的ticket,可用來換取二維碼圖片
        /// </summary>
        public string Ticket { get; set; }
}
 
這裡須要留意的是,當用戶掃描帶參數的二維碼時,假如用戶沒有存眷以後"號,用戶存眷時,會在新聞體中帶上qrscene_參數,和Ticket,所以這裡界說了兩個屬性:EventKey,Ticket。當給EventKey賦值時,調換失落qrscene_,由於我們真正須要的就是前面的參數。
 
掃描帶參數二維碼事宜
用戶掃描帶場景值二維碼時,能夠推送一下兩種事宜:
 
假如用戶還未存眷"號,則用戶可以存眷"號,存眷後微信會將帶場景值存眷事宜推送給開辟者。
假如用戶曾經存眷"號,則微信會將帶場景值掃描事宜推送給開辟者。、
第一種下面曾經講了,這裡就只解釋下第二種。
 
用戶已存眷時的事宜推送
 
xml包以下:
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[FromUser]]></FromUserName>
<CreateTime>123456789</CreateTime>
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[SCAN]]></Event>
<EventKey><![CDATA[SCENE_VALUE]]></EventKey>
<Ticket><![CDATA[TICKET]]></Ticket>
</xml>
 
對應的實體以下:
/// <summary>
/// 掃描帶參數的二維碼實體
/// </summary>
public class ScanEventMessage : EventMessage
{
 
        /// <summary>
        /// 事宜KEY值,是一個32位無符號整數,即創立二維碼時的二維碼scene_id
        /// </summary>
        public string EventKey { get; set; }
        /// <summary>
        /// 二維碼的ticket,可用來換取二維碼圖片
        /// </summary>
        public string Ticket { get; set; }
}
 
上報地輿地位事宜
當"號開啟上報地輿地位功效後,每次進入"號會話時,用戶贊成上報地輿地位後,都邑在進入時上報地輿地位,或在進入回話後每5秒上報一次地輿地位,"號可以再"平台的後台中修正設置。上報地輿地位時,微信會將上報地輿地位事宜推送到開辟者填寫的url。
 
xml數據包以下:
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>123456789</CreateTime>
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[LOCATION]]></Event>
<Latitude>23.137466</Latitude>
<Longitude>113.352425</Longitude>
<Precision>119.385040</Precision>
</xml>
 
對應的實體以下:
/// <summary>
/// 上報地輿地位實體
/// </summary>
public class LocationEventMessage : EventMessage
{
 
        /// <summary>
        /// 地輿地位緯度
        /// </summary>
        public string Latitude { get; set; }
        /// <summary>
        /// 地輿地位經度
        /// </summary>
        public string Longitude { get; set; }
       /// <summary>
        /// 地輿地位精度
       /// </summary>
        public string Precision { get; set; }
}
 
自界說菜單事宜經常使用的事宜有:click,view,scancode_puth,scancode_waitmsg,location_select。別的還有三種發圖的事宜,因為其實不經常使用,筆者也沒想到應用場景,再次就紛歧一講述了,有興致的可以本身研討下,或許和我停止交換。
 
click事宜推送的xml數據包:
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[FromUser]]></FromUserName>
<CreateTime>123456789</CreateTime>
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[CLICK]]></Event>
<EventKey><![CDATA[EVENTKEY]]></EventKey>
</xml>
 
view事宜推送的xml數據包和click的格局是一樣的,所以界說一個類便可以了,以下:
/// <summary>
/// 通俗菜單事宜,包含click和view
/// </summary>
public class NormalMenuEventMessage : EventMessage
{
 
        /// <summary>
        /// 事宜KEY值,設置的跳轉URL
        /// </summary>
        public string EventKey { get; set; }
}
 
scancode事宜的xml數據包以下:
<xml><ToUserName><![CDATA[ToUserName]]></ToUserName>
<FromUserName><![CDATA[FromUserName]]></FromUserName>
<CreateTime>1419265698</CreateTime>
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[scancode_push]]></Event>
<EventKey><![CDATA[EventKey]]></EventKey>
<ScanCodeInfo><ScanType><![CDATA[qrcode]]></ScanType>
<ScanResult><![CDATA[http://weixin.qq.com/r/JEy5oRLE0U_urVbC9xk2]]></ScanResult>
</ScanCodeInfo>
</xml>
 
對應的實體以下:
/// <summary>
/// 菜單掃描事宜
/// </summary>
public class ScanMenuEventMessage : EventMessage
{
 
        /// <summary>
        /// 事宜KEY值
        /// </summary>
        public string EventKey { get; set; }
        /// <summary>
        /// 掃碼類型。qrcode是二維碼,其他的是條碼
        /// </summary>
        public string ScanType { get; set; }
        /// <summary>
        /// 掃描成果
        /// </summary>
        public string ScanResult { get; set; }
}
 
至此,以後經常使用的事宜類型新聞都已界說終了,聯合上一篇所講的,將xml數據包轉換成對象的完全代碼以下:
public class MessageFactory
{
        private static List<BaseMsg> _queue;
        public static BaseMessage CreateMessage(string xml)
        {
            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秒內未呼應的新聞
            }
            XElement xdoc = XElement.Parse(xml);
            var msgtype = xdoc.Element("MsgType").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 (_queue.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.Now,
                        FromUser = FromUserName,
                        MsgFlag = CreateTime
                    });
                }
                else
                {
                    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.ConvertObj<LinkMessage>(xml);
                case MsgType.LOCATION:
                    return Utils.ConvertObj<LocationMessage>(xml);
                case MsgType.EVENT://事宜類型
                {
                    var eventtype = (Event)Enum.Parse(typeof(Event), xdoc.Element("Event").Value.ToUpper());
                    switch (eventtype)
                    {
                        case Event.CLICK:
                            return Utils.ConvertObj<NormalMenuEventMessage>(xml);
                        case Event.VIEW: return Utils.ConvertObj<NormalMenuEventMessage>(xml);
                        case Event.LOCATION: return Utils.ConvertObj<LocationEventMessage>(xml);
                        case Event.LOCATION_SELECT: return Utils.ConvertObj<LocationMenuEventMessage>(xml);
                        case Event.SCAN: return Utils.ConvertObj<ScanEventMessage>(xml);
                        case Event.SUBSCRIBE: return Utils.ConvertObj<SubEventMessage>(xml);
                        case Event.UNSUBSCRIBE: return Utils.ConvertObj<SubEventMessage>(xml);
                        case Event.SCANCODE_WAITMSG: return Utils.ConvertObj<ScanMenuEventMessage>(xml);
                        default:
                            return Utils.ConvertObj<EventMessage>(xml);
                    }
                } break;
                default:
                    return Utils.ConvertObj<BaseMessage>(xml);
            }
        }
}

願望本文所述對年夜家基於C#的微信開辟有所贊助。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved