• 利用缓存、Timer间隔时间发送微信的实例,很有用的例子


    //Class WechatOfferExcutor

    此类为微信触发类,属于上层调用类,其中有用到用静态变量缓存offer信息,Task异步执行发送方法等

    using Newtonsoft.Json.Linq;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Threading.Tasks;
    using Velites.Utility.SharedLibrary;
    using Newtonsoft.Json;
    using System.Configuration;

    namespace xxx.Peripheral.Wechat
    {
        [ParametrType(typeof(WechatOfferParameter))]
        public class WechatOfferExcutor : MemberOfferExecutorBase<WechatOfferParameter>
        {
            static KeyValuePair<long, WechatOfferParameter> offerInfo = new KeyValuePair<long, WechatOfferParameter>();
            static WechatBatchProcess proc = new WechatBatchProcess(Send);

            protected override IOfferExecutionResult ExecuteWithIDataAndMember(IData data, IMember member, WechatOfferParameter offer)
            {
                bool isValid = AssertHits(data, member, offer);
                LogStub.Log(new LogEntry("txt - AssertHits isValid", LogStub.LOG_LEVEL_ERROR));
                if (isValid && !string.IsNullOrWhiteSpace(offer.Content))
                {
                    string memCode = member.GetProperty(ThreeMMemberEntitySchema.ThreeMMember.CODE).ToString();
                    string toWechat = member.GetProperty(ThreeMMemberEntitySchema.ThreeMMember.WECHAT_OPENID).ToString();

                    List<ImgItem> itemList = new List<ImgItem>()
                    {
                        new ImgItem() {
                        title = offer.Subject,
                        content = offer.Content
                        }
                    };

                    LogEntry entry = new LogEntry(string.Format("txt - 微信发送开始, memCode = {0}, wechatOpenID = {1}, offerID = {2}", memCode, toWechat, offer.OfferID), LogStub.LOG_LEVEL_ERROR);
                    LogStub.Log(entry);

                    proc.AddOpenIDAndSendWechat(offer.OfferID, toWechat, itemList, offer.ExecuteTime);
                    //EmailServiceApiConfigurationHub.Instance.EmailProvider.Provide().Send(wechat);

                    LogEntry endEntry = new LogEntry("txt - 微信发送结束", LogStub.LOG_LEVEL_ERROR);
                    LogStub.Log(endEntry);
                }
                return null;
            }

            private static void Send(List<string> openIDs, List<ImgItem> imgDesc)
            {

                //注意,此处必须为异步调用发送方法,否则可能导致发送超时,以至于发送失败
                Task.Run(() => WechatUtility.SendText(openIDs, imgDesc));
                offerInfo = new KeyValuePair<long, WechatOfferParameter>();
            }

            public bool AssertHits(IData data, IMember member, WechatOfferParameter offer)
            {
                bool ret = true;
                if (data == null || member == null || offer == null || member.GetProperty(ThreeMMemberEntitySchema.ThreeMMember.WECHAT_OPENID) == null
                    || string.IsNullOrWhiteSpace(member.GetProperty(ThreeMMemberEntitySchema.ThreeMMember.WECHAT_OPENID).ToString()))
                {
                    ret = false;
                    return ret;
                }
                return ret;
            }

            public override WechatOfferParameter ParseToParameter(JObject jOffer, IOffer offer)
            {
                if (offerInfo.Key != offer.ID)
                {
                    WechatOfferParameter wechatOffer = base.ParseToParameter(jOffer, offer);
                    wechatOffer.Category = offer.CategoryKey;
                    var offerParameterToken = JToken.Parse(offer.Parameter);
                    if (offerParameterToken["content"] != null)
                    {
                        wechatOffer.Content = offerParameterToken["content"].ToString();
                        wechatOffer.Subject = offer.Name;
                        wechatOffer.OfferID = offer.ID;

                        //此处给发送时间赋值
                        //如果是市场活动,没有执行时间,那么可以设置为当前时间的5分钟之后
                        //测试时可以设置为10秒
                        //wechatOffer.ExecuteTime = DateTime.Now.AddSeconds(10);
                        wechatOffer.ExecuteTime = DateTime.Now.AddMinutes(5);
                        var interval = ConfigurationManager.AppSettings["ActivityInterval"];
                        if (interval != null)
                        {
                            wechatOffer.ExecuteTime = DateTime.Now.AddMinutes(Int32.Parse(interval.ToString()));
                        }

                        if (jOffer != null)
                        {
                            IDictionary<string, JToken> data = JsonConvert.DeserializeObject<JObject>(jOffer.ToString());
                            var item = data.Where(p => p.Key.ToLower() == "executetime");
                            if (item != null && item.Any())
                            {
                                wechatOffer.ExecuteTime = Convert.ToDateTime(item.FirstOrDefault().Value);
                            }
                        }

                        offerInfo = new KeyValuePair<long, WechatOfferParameter>(offer.ID, wechatOffer);
                        return wechatOffer;
                    }
                }
                return offerInfo.Value;
            }
        }
    }

    //Class  WechatBatchProcess

    此类是发送微信的中间处理类,包括了Timer间隔触发等,并发处理Lock机制等,其他的项目可以借鉴此类。

    using System;
    using System.Collections.Generic;
    using System.Configuration;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Timers;

    namespace ThreeM.Peripheral.Wechat
    {
        public class WechatBatchProcess
        {
            List<SendInfo> SendInfoList = new List<SendInfo>();
            Action<List<string>, List<ImgItem>> sendAct { set; get; }
            Timer timer;

            public WechatBatchProcess(Action<List<string>, List<ImgItem>> act)
            {
                timer = new Timer();
                sendAct = act;
                //正式的可以改10分钟,测试时可以为30000即30秒
                timer.Interval = 600000;
                var interval = ConfigurationManager.AppSettings["TimerInterval"];
                if (interval != null)
                {
                    timer.Interval = Int32.Parse(interval);
                }
                timer.AutoReset = false;
                timer.Elapsed += new System.Timers.ElapsedEventHandler(Timers_Timer_Elapsed);
            }

            void Timers_Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
            {
                lock (this)
                {
                    var itemList = SendInfoList.Where(p => p.SendTime <= DateTime.Now).ToList();
                    SendInfoList = SendInfoList.Where(p => p.SendTime > DateTime.Now).ToList();
                    foreach (var item in itemList)
                    {
                        Send(item);
                    }

                    if (SendInfoList.Any())
                    {
                        timer.Start();
                    }
                }
            }

            public void AddOpenIDAndSendWechat(long OfferID, string OpenID, List<ImgItem> ImgDesc, DateTime? SendTime)
            {
                if (!string.IsNullOrWhiteSpace(OpenID) && ImgDesc != null && ImgDesc.Any())
                {
                    lock (this)
                    {
                        var item = SendInfoList.FirstOrDefault(p => p.OfferID == OfferID);
                        if (item == null)
                        {
                            item = new SendInfo()
                            {
                                OfferID = OfferID,
                                OpenidList = new List<string>(),
                                ImgDesc = ImgDesc,
                            };

                            SendInfoList.Add(item);

                        }
                        item.SendTime = SendTime;
                        item.OpenidList.Add(OpenID);
                    }
                    timer.Start();
                }
            }

            private void Send(SendInfo item)
            {
                if (item.OpenidList.Any())
                {
                    sendAct(item.OpenidList, item.ImgDesc);
                }
            }
        }

        public class SendInfo
        {
            public List<string> OpenidList { get; set; }
            public List<ImgItem> ImgDesc { get; set; }
            public long OfferID { get; set; }
            public DateTime? SendTime { get; set; }
        }
    }

    //Class  WechatUtility

    此类为基础工具类,包含了发送微信时需要的HttpPost请求等方法,

    包括文本请求和多张图片请求等,是一个非常有用的工具类

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Net;
    using System.Net.Http;
    using System.Net.Http.Headers;
    using System.Text;
    using System.Threading.Tasks;
    using System.Web;
    using System.Configuration;
    using System.Collections.Specialized;
    using Velites.Utility.SharedLibrary;

    namespace xxx.Peripheral.Wechat
    {
        public class WechatUtility
        {
            public static string SendText(List<string> openIDList, string content)
            {
                string url = ConfigurationManager.AppSettings["wechatImgUrl"];
                string result = string.Empty;

                if (openIDList != null && openIDList.Any() && !string.IsNullOrWhiteSpace(content))
                {
                    string param = string.Format("open_ids={0}&text={1}", string.Join(",",openIDList), content);
                    result = HttpPostData(url, param);
                }
               
                return result;
            }

            public static string SendText(List<string> openIDList, List<ImgItem> imgDesc)
            {
                string url = ConfigurationManager.AppSettings["wechatImgUrl"];
                string result = string.Empty;
                var imgInfo = imgDesc.FirstOrDefault();

                if (openIDList != null && openIDList.Any() && !string.IsNullOrWhiteSpace(imgInfo.content))
                {
                    //微信群发要求至少2个账号才能发送,如果只有一个时,添加一个相同的微信号
                    if (openIDList.Count() == 1)
                    {
                        openIDList.Add(openIDList.FirstOrDefault());
                    }

                    string param = string.Format("open_ids={0}&text={1}", string.Join(",", openIDList), imgInfo.content);
                    result = HttpPostData(url, param);
                }

                return result;
            }

            public static string SendImgAndText(List<string> openIDList, string title, string content, string filePath)
            {
                string url = ConfigurationManager.AppSettings["wechatImgUrl"];
                string result = string.Empty;

                if (openIDList != null && openIDList.Any() && !string.IsNullOrWhiteSpace(content))
                {
                    NameValueCollection col = new NameValueCollection();
                    //col.Add("media", filePath);
                    col.Add("title", title);
                    col.Add("content", content);
                    col.Add("open_ids", string.Join(",", openIDList));

                    result = HttpPostData(url, 60000, "media1", filePath, col);
                }

                return result;
            }

            public static string SendImgAndText(List<string> openIDList, List<ImgItem> imgDesc)
            {
                string url = ConfigurationManager.AppSettings["wechatImgUrl"];
                string result = string.Empty;

                if (openIDList != null && openIDList.Any() && imgDesc != null)
                {
                    Dictionary<string, string> imgDic = new Dictionary<string, string>();
                    foreach (var item in imgDesc)
                    {
                        imgDic.Add(item.name, item.path);
                    }

                    NameValueCollection col = new NameValueCollection();
                    col.Add("imgDesc", Newtonsoft.Json.JsonConvert.SerializeObject(imgDesc));
                    col.Add("open_ids", string.Join(",", openIDList));
                    result = HttpPostData(url, 60000, imgDic, col);
                }

                return result;
            }

            public static string HttpPostData(string url, string param)
            {
                LogEntry entry = new LogEntry("发送微信文本开始-HttpPostData -- " + param, LogStub.LOG_LEVEL_ERROR);
                LogStub.Log(entry);

                var result = string.Empty;
                //注意提交的编码 这边是需要改变的 这边默认的是Default:系统当前编码
                byte[] postData = Encoding.UTF8.GetBytes(param);

                // 设置提交的相关参数
                HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
                Encoding myEncoding = Encoding.UTF8;
                request.Method = "POST";
                request.KeepAlive = false;
                request.AllowAutoRedirect = true;
                request.ContentType = "application/x-www-form-urlencoded";
                request.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR  3.0.04506.648; .NET CLR 3.5.21022; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)";
                request.ContentLength = postData.Length;

                // 提交请求数据
                System.IO.Stream outputStream = request.GetRequestStream();
                outputStream.Write(postData, 0, postData.Length);
                outputStream.Close();

                HttpWebResponse response;
                Stream responseStream;
                StreamReader reader;
                string srcString;
                response = request.GetResponse() as HttpWebResponse;
                responseStream = response.GetResponseStream();
                reader = new System.IO.StreamReader(responseStream, Encoding.GetEncoding("UTF-8"));
                srcString = reader.ReadToEnd();
                result = srcString;   //返回值赋值
                reader.Close();

                entry = new LogEntry("发送微信文本结束-HttpPostData -- " + result, LogStub.LOG_LEVEL_ERROR);
                LogStub.Log(entry);
                return result;
            }

            private static string HttpPostData(string url, int timeOut, string fileKeyName,
                                        string filePath, NameValueCollection stringDict)
            {
                string fileKeyName2 = "media2";
                string filePath2 = @"C:Usersgaoj007Pictures1aliuh.jpg";


                string responseContent;
                var memStream = new MemoryStream();
                var webRequest = (HttpWebRequest)WebRequest.Create(url);
                // 边界符
                var boundary = "---------------" + DateTime.Now.Ticks.ToString("x");
                // 边界符
                var beginBoundary = Encoding.ASCII.GetBytes("--" + boundary + " ");
                var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
                // 最后的结束符
                var endBoundary = Encoding.ASCII.GetBytes("--" + boundary + "-- ");

                // 设置属性
                webRequest.Method = "POST";
                webRequest.Timeout = timeOut;
                webRequest.ContentType = "multipart/form-data; boundary=" + boundary;

                // 写入文件
                const string filePartHeader =
                    "Content-Disposition: form-data; name="{0}"; filename="{1}" " +
                     "Content-Type: application/octet-stream ";
                var header = string.Format(filePartHeader, fileKeyName, filePath);
                var headerbytes = Encoding.UTF8.GetBytes(header);

                memStream.Write(beginBoundary, 0, beginBoundary.Length);
                memStream.Write(headerbytes, 0, headerbytes.Length);

                var buffer = new byte[1024];
                int bytesRead; // =0

                while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
                {
                    memStream.Write(buffer, 0, bytesRead);
                }

                //第二章图片
                //memStream.Write(beginBoundary, 0, beginBoundary.Length);

               
                //var aaa = Encoding.ASCII.GetBytes(" --" + boundary + " ");
                //memStream.Write(aaa, 0, aaa.Length);

                string nxetFileFormat = " --" + boundary + " " + filePartHeader;

                header = string.Format(nxetFileFormat, fileKeyName2, filePath2);
                headerbytes = Encoding.UTF8.GetBytes(header);

                memStream.Write(headerbytes, 0, headerbytes.Length);
                fileStream = new FileStream(filePath2, FileMode.Open, FileAccess.Read);
                while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
                {
                    memStream.Write(buffer, 0, bytesRead);
                }

                // 写入字符串的Key
                var stringKeyHeader = " --" + boundary +
                                       " Content-Disposition: form-data; name="{0}"" +
                                       " {1} ";

                foreach (byte[] formitembytes in from string key in stringDict.Keys
                                                 select string.Format(stringKeyHeader, key, stringDict[key])
                                                     into formitem
                                                     select Encoding.UTF8.GetBytes(formitem))
                {
                    memStream.Write(formitembytes, 0, formitembytes.Length);
                }

                // 写入最后的结束边界符
                memStream.Write(endBoundary, 0, endBoundary.Length);

                webRequest.ContentLength = memStream.Length;

                var requestStream = webRequest.GetRequestStream();

                memStream.Position = 0;
                var tempBuffer = new byte[memStream.Length];
                memStream.Read(tempBuffer, 0, tempBuffer.Length);
                memStream.Close();

                requestStream.Write(tempBuffer, 0, tempBuffer.Length);
                requestStream.Close();

                var httpWebResponse = (HttpWebResponse)webRequest.GetResponse();

                using (var httpStreamReader = new StreamReader(httpWebResponse.GetResponseStream(),
                                                                Encoding.GetEncoding("utf-8")))
                {
                    responseContent = httpStreamReader.ReadToEnd();
                }

                fileStream.Close();
                httpWebResponse.Close();
                webRequest.Abort();

                return responseContent;
            }


            private static string HttpPostData(string url, int timeOut, Dictionary<string, string> imgDic, NameValueCollection stringDict)
            {
                LogEntry entry = new LogEntry("发送微信图片开始-HttpPostData open_ids-- " + stringDict["open_ids"], LogStub.LOG_LEVEL_ERROR);
                LogStub.Log(entry);
                try
                {
                    entry = new LogEntry("发送微信图片开始-HttpPostData imgDic-- " + string.Join(",", imgDic), LogStub.LOG_LEVEL_ERROR);
                    LogStub.Log(entry);

                    entry = new LogEntry("发送微信图片开始-HttpPostData imgDic-- first--" + imgDic.FirstOrDefault().Key + " -- " +
                    imgDic.FirstOrDefault().Value + "--last--" + imgDic.LastOrDefault().Key + " -- " + imgDic.LastOrDefault().Value + "--count--" + imgDic.Count(), LogStub.LOG_LEVEL_ERROR);
                    LogStub.Log(entry);

                    var firstImg = imgDic.FirstOrDefault();
                    string fileKeyName = firstImg.Key;
                    string filePath = firstImg.Value;

                    string responseContent;
                    var memStream = new MemoryStream();
                    var webRequest = (HttpWebRequest)WebRequest.Create(url);
                    // 边界符
                    var boundary = "---------------" + DateTime.Now.Ticks.ToString("x");
                    // 边界符
                    var beginBoundary = Encoding.ASCII.GetBytes("--" + boundary + " ");
                    //var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);

                    // 最后的结束符
                    var endBoundary = Encoding.ASCII.GetBytes("--" + boundary + "-- ");

                    // 设置属性
                    webRequest.Method = "POST";
                    webRequest.Timeout = timeOut;
                    webRequest.ContentType = "multipart/form-data; boundary=" + boundary;

                    // 写入文件
                    const string filePartHeader =
                        "Content-Disposition: form-data; name="{0}"; filename="{1}" " +
                         "Content-Type: application/octet-stream ";
                    var header = string.Format(filePartHeader, fileKeyName, filePath);
                    var headerbytes = Encoding.UTF8.GetBytes(header);

                    memStream.Write(beginBoundary, 0, beginBoundary.Length);
                    memStream.Write(headerbytes, 0, headerbytes.Length);

                    //var buffer = new byte[1024];
                    //int bytesRead; // =0

                    //while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
                    //{
                    //    memStream.Write(buffer, 0, bytesRead);
                    //}

                    WebClient wc = new WebClient();
                    byte[] buffer = wc.DownloadData(filePath);
                    memStream.Write(buffer, 0, buffer.Length);

                    string imgName = string.Empty;
                    string imgPath = string.Empty;
                    foreach (var img in imgDic.Where(p => p.Key != fileKeyName))
                    {
                        imgName = img.Key;
                        imgPath = img.Value;

                        string nxetFileFormat = " --" + boundary + " " + filePartHeader;

                        header = string.Format(nxetFileFormat, imgName, imgPath);
                        headerbytes = Encoding.UTF8.GetBytes(header);

                        memStream.Write(headerbytes, 0, headerbytes.Length);
                        //fileStream = new FileStream(imgPath, FileMode.Open, FileAccess.Read);
                        //while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
                        //{
                        //    memStream.Write(buffer, 0, bytesRead);
                        //}

                        buffer = wc.DownloadData(imgPath);
                        memStream.Write(buffer, 0, buffer.Length);
                    }

                    // 写入字符串的Key
                    var stringKeyHeader = " --" + boundary +
                                           " Content-Disposition: form-data; name="{0}"" +
                                           " {1} ";

                    foreach (byte[] formitembytes in from string key in stringDict.Keys
                                                     select string.Format(stringKeyHeader, key, stringDict[key])
                                                         into formitem
                                                         select Encoding.UTF8.GetBytes(formitem))
                    {
                        memStream.Write(formitembytes, 0, formitembytes.Length);
                    }
                    // 写入最后的结束边界符
                    memStream.Write(endBoundary, 0, endBoundary.Length);

                    webRequest.ContentLength = memStream.Length;
                    var requestStream = webRequest.GetRequestStream();
                    memStream.Position = 0;
                    var tempBuffer = new byte[memStream.Length];
                    memStream.Read(tempBuffer, 0, tempBuffer.Length);
                    memStream.Close();
                    requestStream.Write(tempBuffer, 0, tempBuffer.Length);
                    requestStream.Close();

                    var httpWebResponse = (HttpWebResponse)webRequest.GetResponse();
                    using (var httpStreamReader = new StreamReader(httpWebResponse.GetResponseStream(),
                                                                    Encoding.GetEncoding("utf-8")))
                    {
                        responseContent = httpStreamReader.ReadToEnd();
                    }
                    //fileStream.Close();
                    httpWebResponse.Close();
                    webRequest.Abort();

                    entry = new LogEntry("发送微信图片结束-HttpPostData -- " + responseContent, LogStub.LOG_LEVEL_ERROR);
                    LogStub.Log(entry);

                    return responseContent;
                }
                catch (Exception er)
                {
                    entry = new LogEntry("发送微信图文发生异常 -- HttpPostData -- " + er.ToString(), LogStub.LOG_LEVEL_ERROR);
                    LogStub.Log(entry);
                }

                return null;
            }

        }
    }


     


     

  • 相关阅读:
    (十)安装YAML
    (十四)日志
    Android自动化测试------monkeyrunner(六)
    Android自动化测试------monkey日志管理(五)
    如何学好一门编程语言
    linux vi hjkl由来
    .net 微服务CICD 好文章
    APPCMD 精心整理 有点赞的吗
    APPCMD 命令合集
    APPCMD 使用手册
  • 原文地址:https://www.cnblogs.com/itjeff/p/4602700.html
Copyright © 2020-2023  润新知