zoukankan      html  css  js  c++  java
  • 使用Senparc.Weixin.WxOpen开发高可用的微信小程序

    Senparc.Weixin SDK介绍

    Senparc.Weixin SDk是目前.net平台上使用率最高的微信SDK,除硬件平台暂未发布以外覆盖了所有微信平台模块,自2013年免费开源起已经持续更新了4年,是GitHub上目前Star和Fork数最多的中国C#开源项目。

    目前大多数模块都支持了.net 4.0 / .net 4.5 / .net core 三个版本,Senparc官方计划在2017年将新增.net 4.6.2版本,并着力强化.net core版本,在7月左右会停止对.net 4.0版本的更新。

    其中,小程序的模块命名为Senparc.Weixin.WxOpen,Nuget地址:

    https://www.nuget.org/packages/Senparc.Weixin.WxOpen

    v1.0版本已于2017年1月9日凌晨同步上线!

    Senparc.Wexin SDK系列库:

    过去的4年时间,Senparc团队总共迭代发布了100多个稳定版本,目前总体框架已经比较完善,可以应对超高并发在内的各种系统环境。

    以下是官方提供的一些资源:

    官网:http://weixin.senparc.com/

    源代码(包含Demo):https://github.com/JeffreySu/WeiXinMPSDK

    在线Demo(包含Nuget项目入口):http://sdk.weixin.senparc.com/

    Demo公众号:盛派网络小助手

    公众号开发系列教程:http://www.cnblogs.com/szw/p/weixin-course-index.html 

    下载类库chm帮助文档:http://sdk.weixin.senparc.com/Document

    在线类库帮助文档:http://doc.weixin.senparc.com/

    微信开发资源汇总项目:https://github.com/JeffreySu/WeixinResource

    Senparc.Weixin SDK交流QQ群:342319110

    小程序开发交流QQ群:108830388 

    微信平台生态关系
    加上小程序之后,整个公众号的平台生态又多了一环,根据开发代码体量和包含关系(尤其是核心重叠部分),目前大概是下面这样的场景:

    整个2016年,开发者们被微信小程序吊足了胃口,每每微信官方有小程序的动态发布,都会被刷屏,大众对微信小程序的关注程度可见一斑。

    对于开发者来说,无论微信小程序的实际商业应用广度或是被接受度如何,这都将是一块熟悉又陌生的广阔的处女地。

    由于小程序的多数规则和微信公众号基本一致,因此我们的小程序模块(Senparc.Weixin.WxOpen.dll)多数代码是从公众号模块(Senparc.Weixin.MP.dll)移植过来的。

    微信官方为小程序准备了比较细致的文档和教程(这一点和当初公众号相比简直不在一个级别上),以下是一些重要的线上资源:

    小程序开发文:https://mp.weixin.qq.com/debug/wxadoc/dev/

    小程序设计指南:https://mp.weixin.qq.com/debug/wxadoc/design/

    开发工具下载:
    https://mp.weixin.qq.com/debug/wxadoc/dev/devtools/download.html

    下文将整理目前为止对小程序后端开发最为重要的知识点、注意点进行介绍,或给出对应资源的地址,并就和微信公众号相关的技能给出相关的索引。

    对于一个在高并发场景下保持高可用性的小程序来说,这几个方面的处理细节是不可忽视的:

    消息处理

    上下文

    消息加密

    AccessToken令牌处理

    高级接口

    异步开发

    分布式缓存

    同步锁

    WebSocket

    跟踪日志及异常处理

    消息处理
    微信小程序在进入客服会话状态之后,即可与客服进行对话,可以发送文字或图片信息,和公众号不同的是,目前小程序的消息系统是不能进行直接回复的,必须使用异步的方式调用“客服接口”推送消息(下文会讲到),为此我们优化了Senparc.Weixin SDK中的消息处理流程:MessageHandler。

    MessageHandler是一个信消息的处理模块,也是整个微信开发过程中不可缺少的一部分。在MessageHandler中,开发者可以非常轻松地处理所有类型的微信消息。小程序的MessageHandler类叫做WxOpenMessageHandler。

    在ASP.NET MVC我们只需要如下几步就可实现对消息的处理(和微信公众号一致)。

    第一步:创建上上下文类,CustomWxOpenMessageContext.cs:

    有关WxOpenMessageContext(上下文)的内容下文会讲到。

    CustomWxOpenMessageContext.cs 代码如下:

    using Senparc.Weixin.Context;

    using Senparc.Weixin.WxOpen.Entities;

    namespace Senparc.Weixin.MP.Sample.CommonService.WxOpenMessageHandler

    {
    public class CustomWxOpenMessageContext : MessageContext<IRequestMessageBase,IResponseMessageBase>

    {
    public CustomWxOpenMessageContext()

    {
    base.MessageContextRemoved += CustomMessageContext_MessageContextRemoved;

    }

    /// <summary>

    /// 当上下文过期,被移除时触发的时间

    /// </summary>

    /// <param name="sender"></param>

    /// <param name="e"></param>

    void CustomMessageContext_MessageContextRemoved(object sender, Senparc.Weixin.Context.WeixinContextRemovedEventArgs<IRequestMessageBase,IResponseMessageBase> e)

    {
    /* 注意,这个事件不是实时触发的(当然你也可以专门写一个线程监控)

    * 为了提高效率,根据WeixinContext中的算法,这里的过期消息会在过期后下一条请求执行之前被清除

    */

    var messageContext = e.MessageContext as CustomWxOpenMessageContext;

    if (messageContext == null)

    {
    return;//如果是正常的调用,messageContext不会为null

    }

    //TODO:这里根据需要执行消息过期时候的逻辑,下面的代码仅供参考

    //Log.InfoFormat("{0}的消息上下文已过期",e.OpenId);

    //api.SendMessage(e.OpenId, "由于长时间未搭理客服,您的客服状态已退出!");

    }

    }

    }

    源码:

    第二步:创建自定义 CustomWxOpenMessageHandler.cs:

    CustomWxOpenMessageHandler.cs 代码如下:

    using System.IO;

    using System.Web.Configuration;

    using Senparc.Weixin.MP.Entities;

    using Senparc.Weixin.MP.Entities.Request;

    using Senparc.Weixin.MP.MessageHandlers;

    using IRequestMessageBase = Senparc.Weixin.MP.Entities.IRequestMessageBase;

    using IResponseMessageBase = Senparc.Weixin.MP.Entities.IResponseMessageBase;

    namespace Senparc.Weixin.MP.Sample.CommonService.WxOpenMessageHandler

    {
    /// <summary>

    /// 自定义MessageHandler

    /// 把MessageHandler作为基类,重写对应请求的处理方法

    /// </summary>

    public partial class CustomWxOpenMessageHandler : MessageHandler<CustomWxOpenMessageContext>

    {
    private string appId = WebConfigurationManager.AppSettings["WxOpenAppId"];

    private string appSecret = WebConfigurationManager.AppSettings["WxOpenAppSecret"];

    public CustomWxOpenMessageHandler(Stream inputStream, PostModel postModel, int maxRecordCount = 0)

    : base(inputStream, postModel, maxRecordCount)

    {
    //这里设置仅用于测试,实际开发可以在外部更全局的地方设置,

    //比如MessageHandler<MessageContext>.GlobalWeixinContext.ExpireMinutes = 3。

    WeixinContext.ExpireMinutes = 3;

    if (!string.IsNullOrEmpty(postModel.AppId))

    {
    appId = postModel.AppId;//通过第三方开放平台发送过来的请求

    }

    //在指定条件下,不使用消息去重

    base.OmitRepeatedMessageFunc = requestMessage =>

    {
    var textRequestMessage = requestMessage as RequestMessageText;

    if (textRequestMessage != null && textRequestMessage.Content == "容错")

    {
    return false;

    }

    return true;

    };

    }

    public override void OnExecuting()

    {
    //测试MessageContext.StorageData

    if (CurrentMessageContext.StorageData == null)

    {
    CurrentMessageContext.StorageData = 0;

    }

    base.OnExecuting();

    }

    public override void OnExecuted()

    {
    base.OnExecuted();

    CurrentMessageContext.StorageData = ((int)CurrentMessageContext.StorageData) + 1;

    }

    /// <summary>

    /// 处理文字请求

    /// </summary>

    /// <returns></returns>

    public override IResponseMessageBase OnTextRequest(RequestMessageText requestMessage)

    {
    //TODO:这里的逻辑可以交给Service处理具体信息,参考OnLocationRequest方法或/Service/LocationSercice.cs

    //这里可以进行数据库记录或处理

    return new SuccessResponseMessage();

    }

    public override IResponseMessageBase OnImageRequest(RequestMessageImage requestMessage)

    {
    //发来图片,进行处理

    return DefaultResponseMessage(requestMessage);

    }

    public override IResponseMessageBase DefaultResponseMessage(IRequestMessageBase requestMessage)

    {
    //所有没有被处理的消息会默认返回这里的结果

    return new SuccessResponseMessage();

    //return new SuccessResponseMessage();等效于:

    //base.TextResponseMessage = "success";

    //return null;

    }

    }

    }

    源码:

    微信小程序的MessageHandler和微信公众号的MessageHandler的一些区别见下表,这也是微信小程序和微信公众号在消息处理上的一些差别,务必须要注意!


    微信公众号

    微信小程序

    请求消息类型

    众多

    1、 文本消息

    2、 图片消息

    请求事件类型

    众多

    进入会话(客服)事件

    返回类型

    1、基于

    Senparc.Weixin.MP.

    ResponseMessageBase

    的子类

    2、返回空字符串或"success"

    (也可以使用SuccessResponseMessage)

    只返回空字符串或"success"

    (也可以使用SuccessResponseMessage)

    注意:微信小程序的文本及图片类型请求消息,是在“客服对话”的状态下转发到开发者服务器的。

    第三步:创建Conntroller,为使用MessageHandler做准备:

    using System;

    using System.IO;

    using System.Web.Configuration;

    using System.Web.Mvc;

    using Senparc.Weixin.MP.Entities.Request;

    using Senparc.Weixin.MP.MvcExtension;

    using Senparc.Weixin.MP.Sample.CommonService. WxOpenMessageHandler;

    namespace Senparc.Weixin.MP.Sample.Controllers.WxOpen

    {
    /// <summary>

    /// 微信小程序Controller

    /// </summary>

    public partial class WxOpenController : Controller

    {
    public static readonly string Token = WebConfigurationManager.AppSettings["WxOpenToken"];//与微信公众账号后台的Token设置保持一致,区分大小写。

    public static readonly string EncodingAESKey = WebConfigurationManager.AppSettings["WxOpenEncodingAESKey"];//与微信公众账号后台的EncodingAESKey设置保持一致,区分大小写。

    public static readonly string AppId = WebConfigurationManager.AppSettings["WxOpenAppId"];//与微信公众账号后台的AppId设置保持一致,区分大小写。

    }

    }

    源码:

    第四步:添加Action,使用MessageHandler

    微信小程序的Url验证逻辑和微信公众号是一致的,为此我们需要添加2个Action来分别处理验证(GET)的请求和微信转发的消息请求(POST)。

    GET请求:

    /// <summary>

    /// GET请求用于处理微信小程序后台的URL验证

    /// </summary>

    /// <returns></returns>

    [HttpGet]

    [ActionName("Index")]

    public ActionResult Get(PostModel postModel, string echostr)

    {
    if (CheckSignature.Check(postModel.Signature, postModel.Timestamp, postModel.Nonce, Token))

    {
    return Content(echostr); //返回随机字符串则表示验证通过

    }

    else

    {
    return Content("failed:" + postModel.Signature + "," + MP.CheckSignature.GetSignature(postModel.Timestamp, postModel.Nonce, Token) + "。" +

    "如果你在浏览器中看到这句话,说明此地址可以被作为微信小程序后台的Url,请注意保持Token一致。");

    }

    }

    GET请求部署完毕之后,我们直接使用浏览器打开,可以看到一条提示,表明此Action已经可以被访问:

    POST请求:

    /// <summary>

    /// 用户发送消息后,微信平台自动Post一个请求到这里,并等待响应XML。

    /// </summary>

    [HttpPost]

    [ActionName("Index")]

    public ActionResult Post(PostModel postModel)

    {
    if (!CheckSignature.Check(postModel.Signature, postModel.Timestamp, postModel.Nonce, Token))

    {
    return Content("参数错误!");

    }

    postModel.Token = Token;//根据自己后台的设置保持一致

    postModel.EncodingAESKey = EncodingAESKey;//根据自己后台的设置保持一致

    postModel.AppId = AppId;//根据自己后台的设置保持一致

    var maxRecordCount = 50;

    //第一步:MessageHandler,对微信请求的详细判断操作都在这里面。

    var messageHandler = new CustomMessageHandler(Request.InputStream, postModel, maxRecordCount);

    //第二步:执行微信处理过程

    messageHandler.Execute();

    //第三步:返回结果

    return new FixWeixinBugWeixinResult(messageHandler);

    }

    核心的“三部曲”和微信公众号保持了完全的一致。

    现在,只需要在Web.config中配置正确的AppId等信息,就可以在小程序后台完成“消息推送”接口的配置:

    随后,我们就能在微信小程序的预览状态或正式发布之后,测试消息处理能力,下文中的“高级接口”部分我们会丰富消息处理过程,并进行发布。

    上下文
    在CustomWxOpenMessageHandler的基类设置的时候,我们看到使用了一个叫MessageContext的泛型(MessageHandler<MessageContext>),这个MessageContext是Senparc.Weixin SDK提供的一个默认的消息上下文处理类。

    MessageContext主要用于消息由微信服务器统一转发的情况下,无法针对单个用户对话使用Session的情况,同时也具有消息去重等方法。这个默认的类已经能够处理最基础的情况,如果您的应用不是很复杂,那么直接用这个类就行了。如果项目比较复杂,您也可以根据自己的需要创建一个自己的类(实现IMessageContext接口),或继承这个类之后,再扩展更多的属性(例如工作流和比较特殊的分布式缓存,等等)。

    上下文除了弥补Session的作用存储个人数据以外,还提供了完整对话记录的保存,对于机器人回复等场景都具有非常重要的作用。

    Senparc.Weixin SDk已经对上下文功能进行了比较充分的解耦,使之成为一个独立的模块,可以进行自由的重写和扩展。开发者可以自由设置上下文保存的时间及条数。

    微信服务器在没有迅速收到应用程序服务器回应的情况下,在5秒有效等待时间内,内会连续发送共计3条相同的消息,这会给程序带来一些困扰,因此,消息去重在MessageHandler里面是一个非常重要的“标配”。

    消息去重已经在Senparc.Weixin.MP.MessageHandlers.MessageHandler.cs的OnExecuting()方法中实现,默认为开启,如果在某些特殊需求下需要关闭,可以将OmitRepeatedMessage参数设置为false。

    由于去重方法是在OnExecuting()方法中优先执行,因此OmitRepeatedMessage的设置必须早于OnExecuting(),可以在MessageHandler的构造函数中,也可以在MessageHandler实例化之后进行设置,例如:

    var messageHandler = new CustomMessageHandler(Request.InputStream, postModel);//接收消息(第一步)

    messageHandler. OmitRepeatedMessage = false;

    messageHandler.Execute();//执行微信处理过程

    消息加密
    出于消息安全考虑,微信提供了消息加密的方法,并且推荐使用。微信公众号的后台会要求开发者填写EncodingAESKey,或自动生成,如下图:

    消息加密的状态在MessageHandler内部已经进行了自动判断及相关解码、编码的处理,因此开发者无因为消息加密的类型编写任何代码,只需要在微信后台按需设置即可。

    在数据格式方面,微信小程序比微信公众号多提供了一个可选的JSON数据格式, Senparc.Weixin.WxOpen.dll将在v1.2版本提供对JSON格式的支持,目前请使用和微信公众号相同的XML格式。

    AccessToken令牌处理
    AccessToken是用于提供高级接口请求身份验证的令牌,由AppId及Secret通过API获得。AppId及Secret可以在微信小程序后台的【设置】>【开发设置】中找到或生成。

    微信小程序的AccessToken令牌规则及使用方式与公众号完全兼容,因此我们在小程序模块中,共享了公众号的AccessToken处理模块:AccessTokenContainer。

    AccessTokenContainer的作用是自动处理AccessToken的过期、储存(包括分布式缓存)等问题,让开发者可以专注到逻辑开发中,从而彻底忽略由于AccessToken延伸出来的一堆麻烦事。

    AccessTokenContainer的使用要求开发者在Global或App_Start中对AppId及Secret进行注册(当然也可以在需要用到AccessToken之前的任意程序位置进行),例如:

    protected void Application_Start()

    {
    /* 微信配置开始

    *

    * 建议按照以下顺序进行注册,尤其须将缓存放在第一位!

    */

    RegisterWeixinCache(); //注册分布式缓存(按需,如果需要,必须放在第一个)

    RegisterWeixinThreads(); //激活微信缓存及队列线程(必须)

    RegisterSenparcWeixin(); //注册Demo所用微信公众号的账号信息(按需)

    RegisterSenparcQyWeixin(); //注册Demo所用微信企业号的账号信息(按需)

    RegisterWeixinPay(); //注册微信支付(按需)

    RegisterWeixinThirdParty(); //注册微信第三方平台(按需)

    ConfigWeixinTraceLog(); //配置微信跟踪日志(按需)

    /* 微信配置结束 */

    }

    /// <summary>

    /// 注册Demo所用微信公众号的账号信息

    /// </summary>

    private void RegisterSenparcWeixin()

    {
    //注册公众号

    AccessTokenContainer.Register(

    System.Configuration.ConfigurationManager.AppSettings["WeixinAppId"],

    System.Configuration.ConfigurationManager.AppSettings["WeixinAppSecret"],

    "【盛派网络小助手】公众号");

    //注册小程序(完美兼容)

    AccessTokenContainer.Register(

    System.Configuration.ConfigurationManager.AppSettings["WxOpenAppId"],

    System.Configuration.ConfigurationManager.AppSettings["WxOpenAppSecret"],

    "【盛派互动】小程序");

    }

    上述红色的代码是和注册AccessTokenContainer有关的,实际上只需要添加3行代码,即可完全忘掉AccessToken这回事。

    高级接口
    小程序目前提供了包括二维码、Code换取、模板消息等少量的高级接口,并且兼容了微信公众号的文本及图片类型的客服接口(48小时内主动推送)。

    Senparc.Weixin SDK为高级接口提供了非常高效、便捷的处理方式,用户如果已经注册了AppId及Secret,那么在调用高级接口的时候无需再提供AccessToken,只需提供AppId即可,AccessTokenContainer会自动识别传入的字符串属于AppId或是Secret,并对令牌过期等问题进行自动处理,确保在最大的可能性下面,开发者可以一次性得到期望的响应结果。

    例如上文介绍的消息处理过程中,我们可以使用高级接口来即时回复用户:

    /// <summary>

    /// 处理文字请求

    /// </summary>

    /// <returns></returns>

    public override IResponseMessageBase OnTextRequest(RequestMessageText requestMessage)

    {
    //TODO:这里的逻辑可以交给Service处理具体信息,参考OnLocationRequest方法或/Service/LocationSercice.cs

    //这里可以进行数据库记录或处理

    //发送一条客服消息回复用户

    var result = new StringBuilder();

    result.AppendFormat("您刚才发送了文字信息:{0} ", requestMessage.Content);

    if (CurrentMessageContext.RequestMessages.Count > 1)

    {
    result.AppendFormat("您刚才还发送了如下消息({0}/{1}): ", CurrentMessageContext.RequestMessages.Count,

    CurrentMessageContext.StorageData);

    for (int i = CurrentMessageContext.RequestMessages.Count - 2; i >= 0; i--)

    {
    var historyMessage = CurrentMessageContext.RequestMessages[i];

    string content = null;

    if (historyMessage is RequestMessageText)

    {
    content = (historyMessage as RequestMessageText).Content;

    }

    else if (historyMessage is RequestMessageEvent_UserEnterTempSession)

    {
    content = "[进入客服]";

    }

    else

    {
    content = string.Format("[非文字信息:{0}]", historyMessage.GetType().Name);

    }

    result.AppendFormat("{0} 【{1}】{2} ",

    historyMessage.CreateTime.ToShortTimeString(),

    historyMessage.MsgType.ToString(),

    content

    );

    }

    result.AppendLine(" ");

    }

    //处理微信换行符识别问题

    var msg = result.ToString().Replace(" ", " ");

    //使用微信公众号的接口,完美兼容

    Senparc.Weixin.MP.AdvancedAPIs.CustomApi.SendText(appId, WeixinOpenId, msg);

    return new SuccessResponseMessage();

    //和公众号一样回复XML是无效的:

    // return new SuccessResponseMessage()

    // {
    // ReturnText = string.Format(@"<?xml version=""1.0"" encoding=""utf-8""?>

    //<xml>

    // <ToUserName><![CDATA[{0}]]></ToUserName>

    // <FromUserName><![CDATA[{1}]]></FromUserName>

    // <CreateTime>1357986928</CreateTime>

    // <MsgType><![CDATA[text]]></MsgType>

    // <Content><![CDATA[TNT2]]></Content>

    //</xml>",requestMessage.FromUserName,requestMessage.ToUserName)

    // };

    }

    其中高级接口调用代码只需要一行:

    Senparc.Weixin.MP.AdvancedAPIs.CustomApi.SendText(appId, WeixinOpenId, msg);

    进入客服的状态也用同样的方式处理:

    public override IResponseMessageBase OnEvent_UserEnterTempSessionRequest(RequestMessageEvent_UserEnterTempSession requestMessage)

    {
    //进入客服

    var msg = "欢迎您!这条消息来自Senparc.Weixin进入客服事件。";

    Senparc.Weixin.MP.AdvancedAPIs.CustomApi.SendText(appId, WeixinOpenId, msg);

    return DefaultResponseMessage(requestMessage);

    }

    我们再来改写图片处理方式(注意,这次我们会使用异步模式):

    public override IResponseMessageBase OnImageRequest(RequestMessageImage requestMessage)

    {
    //发来图片,进行处理

    Task.Factory.StartNew(async () =>

    {
    await Senparc.Weixin.MP.AdvancedAPIs.CustomApi.SendTextAsync(appId, WeixinOpenId, "刚才您发送了这张图片:");

    await Senparc.Weixin.MP.AdvancedAPIs.CustomApi.SendImageAsync(appId, WeixinOpenId, requestMessage.MediaId);

    });

    return DefaultResponseMessage(requestMessage);

    }

    上述代码中,使用了和微信公众号兼容的图片高级接口。

    在微信小程序的预览或发布状态下,用户可以收到如下回复:

    进入客服状态及发送文字及回复

    发送图片及回复

    异步开发
    在高并发的场景下,异步编程可以说是入门级的一个必备。

    在Senparc.Weixin SDK中,我们总共提供了400多个异步方法,除可能的个别遗漏以外,已经覆盖了所有的高级接口,方法命名规则为同步方法名后加Async。我们的目标是覆盖所有并发场景下会成为瓶颈的接口,其中MessageHandler的异步版本也已经计划在Senparc.Weixin.dll v4.11中上线。

    异步方法的使用在.NET 4.5之后已经变得非常简单,例如下面的是文字消息的同步方法调用:

    AdvancedAPIs.CustomApi.SendText(appId, WeixinOpenId, "这是一条文字信息");

    使用异步方法:

    Task.Factory.StartNew(async () =>

    {
    await AdvancedAPIs.CustomApi.SendTextAsync(appId, WeixinOpenId, "这是一条文字信息");

    });

    分布式缓存
    在需要考虑缓存生命周期、并发量等诸多因素的情况下,我们通常都会采用负载均衡来环节服务器压力,这种情况下几乎都会用到分布式缓存。

    尤其对于微信的公众号的AccessToken,同一时间内真正有效的AccessToken只有一个(当然也存在一段时间的有效缓存,企业号是没有这个问题的),如果多台服务器各自管理自己内存中的AccessToken数据,必然会导致一场不会停止的“令牌争夺战”:各自判断AccessToken失效之后,刷新私有的AccessToken,直到当天的AccessToken获取次数被用完,系统无法提供高级接口服务。

    这种情况下就需要一个统一的“数据中心”来储存AccessToken等独一份的信息,实现的方法有很多:分布式缓存、数据库、文件、数据交换模块等等,通常我们会首选分布式缓存。

    Senparc.Weixin SDK为分布式缓存做了比较细致的架构,可以适应许多复杂情况下微信对于缓存的需求,并且提供了Memcached(Senparc.Weixin.Cache.Memcached.dll)和Redis(Senparc.Weixin.Cache.Redis.dll)两种缓存的实现。相比之下我们更推荐Redis,也在Redis模块上花了更多的精力进行优化。

    Senparc.Weixin SDK已经实现了缓存策略的热切换,开发者可以在任意时候切换缓存状态(本地缓存、Reids、Memcached或自己扩展的任何缓存策略),并且不会影响到AccessTokenContainner等模块的稳定性。

    Senparc.Weixin SDK默认缓存采用单机的本地内存,缓存生命周期和应用程序紧密联系,如果要突破这样的限制,或是在分布式环境中使用,就需要引入外部的缓存,以Redis缓存为例,我们只需要3行代码即可完成切换:

    //定义Redis连接字符串

    var redisConfiguration = System.Configuration.ConfigurationManager.AppSettings["Cache_Redis_Configuration"];

    //设置Redis连接字符串

    RedisManager.ConfigurationOption = redisConfiguration;

    //指定缓存策略实例

    CacheStrategyFactory.RegisterObjectCacheStrategy(() => RedisObjectCacheStrategy.Instance);

    只要配置正确,接下来的存取、序列化、储存格式、key管理等问题开发者都不必关心,无论使用什么缓存从策略,逻辑代码都无需做任何修改,Senparc.Weixin SDK的缓存策略接口已经对行为进行了严格规范,实现类会针对不同的缓存进行差别化的处理。

    同步锁、WebSocket、跟踪日志及异常处理
    请期待下一篇。

    本文的Demo已经发布到GitHub的开源项目中,位于:https://github.com/JeffreySu/WeiXinMPSDK/tree/master/src/Senparc.Weixin.MP.Sample

    以上部分内容节选自正在编写的《微信公众平台快速开发(拟)》图书,编写工作已经进入尾声,预计于年后进入出版流程,欢迎参与众筹:




    .NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注


    ————————————————
    版权声明:本文为CSDN博主「dotNET跨平台」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/sD7O95O/article/details/78096919

  • 相关阅读:
    类继承
    抽象基类 纯虚函数
    虚函数
    Java网络通信
    Java补补补
    刷LeetCode吧
    贝叶斯网络的
    vscode添加vue模板
    vue--项目实例
    Java01
  • 原文地址:https://www.cnblogs.com/Alex80/p/14726504.html
Copyright © 2011-2022 走看看