C#微信公众号开发之用户上下文WeixinContext和MessageContext

作者:Jeffrey?Su 时间:2022-04-23 09:31:54 

概述

由于微信公众平台的特殊机制,所有的信息都由微信服务器转发而来,因此服务器是无法使用Session对用户会话的上下文进行管理的。

为此Senparc.WeiXin.MP SDK增加了上下文的模块,并集成到了MessageHandler中。

WeixinContext

WeixinContext是所有单个用户上下文(MessageContext)实体的容器(暂且称为全局上下文)。WeixinContext本身不是静态类,意味着您可以在同一个应用中创建多个上下文实体。

同时,一个静态的WeixinContext实例被放入到MessageHandler<TM>中,因此所有项目中由MessageHandler<TM>派生的子类中的WeixinContext是唯一的、全局的(注:TM为实现IMessageContext的类,包括SDK中已经提供的MessageContext)。

因此我们在任何一个实现了MessageHandler<TM>的实例中(比如叫MyMessageHandler),都可以访问到一个类型和名称都叫WeixinContext的对象。

WeixinContext用于保存所用户的上下文(MessageContext),并且提供了一系列的方法,主要方法包括:

/// <summary>
       /// 重置所有上下文参数,所有记录将被清空
       /// </summary>
       public void Restore()
       {
           ...
       }

/// <summary>
       /// 获取MessageContext,如果不存在,返回null
       /// 这个方法的更重要意义在于操作TM队列,及时移除过期信息,并将最新活动的对象移到尾部
       /// </summary>
       /// <param name="userName">用户名(OpenId)</param>
       /// <returns></returns>
       private TM GetMessageContext(string userName)
       {
           ...
       }

/// <summary>
       /// 获取MessageContext
       /// </summary>
       /// <param name="userName">用户名(OpenId)</param>
       /// <param name="createIfNotExists">True:如果用户不存在,则创建一个实例,并返回这个最新的实例
       /// False:用户储存在,则返回null</param>
       /// <returns></returns>
       private TM GetMessageContext(string userName, bool createIfNotExists)
       {
           ...
       }

/// <summary>
       /// 获取MessageContext,如果不存在,使用requestMessage信息初始化一个,并返回原始实例
       /// </summary>
       /// <returns></returns>
       public TM GetMessageContext(IRequestMessageBase requestMessage)
       {
           ...
       }

/// <summary>
       /// 获取MessageContext,如果不存在,使用requestMessage信息初始化一个,并返回原始实例
       /// </summary>
       /// <returns></returns>
       public TM GetMessageContext(IResponseMessageBase responseMessage)
       {
           ...
       }

/// <summary>
       /// 记录请求信息
       /// </summary>
       /// <param name="requestMessage">请求信息</param>
       public void InsertMessage(IRequestMessageBase requestMessage)
       {
           ...
       }

/// <summary>
       /// 记录响应信息
       /// </summary>
       /// <param name="responseMessage">响应信息</param>
       public void InsertMessage(IResponseMessageBase responseMessage)
       {
           ...
       }

/// <summary>
       /// 获取最新一条请求数据,如果不存在,则返回Null
       /// </summary>
       /// <param name="userName">用户名(OpenId)</param>
       /// <returns></returns>
       public IRequestMessageBase GetLastRequestMessage(string userName)
       {
           ...
       }

/// <summary>
       /// 获取最新一条响应数据,如果不存在,则返回Null
       /// </summary>
       /// <param name="userName">用户名(OpenId)</param>
       /// <returns></returns>
       public IResponseMessageBase GetLastResponseMessage(string userName)
       {
           ...
       }

WeixinContext中有两个用于储存用户上下文的对象:MessageCollection及MessageQueue。

这两个对象中的元素集合是重合的,但是MessageQueue对元素进行了排序,以便及时处理掉顶部过期的上下文。

ExpireMinutes用于定义上下文时间有效期,默认为90分钟。可以在程序的任何地方设置设个参数,且立即生效。

PS:MessageQueue中删除过期数据的逻辑以极高的效率运作,开发时无需考虑CPU占用及对象冲突的问题(额外校验时间是否超时)。

MessageContext

MessageContext用于保存单个用户的上下文信息,被储存在WeixinContext的MessageCollection及MessageQueue对象中。 IMessageContext定义如下:

public interface IMessageContext
   {
       /// <summary>
       /// 用户名(OpenID)
       /// </summary>
       string UserName { get; set; }
       /// <summary>
       /// 最后一次活动时间(用户主动发送Resquest请求的时间)
       /// </summary>
       DateTime LastActiveTime { get; set; }
       /// <summary>
       /// 接收消息记录
       /// </summary>
       List<IRequestMessageBase> RequestMessages { get; set; }
       /// <summary>
       /// 响应消息记录
       /// </summary>
       List<IResponseMessageBase> ResponseMessages { get; set; }
       /// <summary>
       /// 临时储存数据,如用户状态等,出于保持.net 3.5版本,这里暂不使用dynamic
       /// </summary>
       object StorageData { get; set; }
   }

您可以根据自己的需要创建自己的类,实现这个接口,并且被WeixinContext使用。当然如果你的要求不是那么特殊,而且你比较懒的话,SDK提供了一个默认的MessageContext实现:

/// <summary>
   /// 微信消息上下文(单个用户)
   /// </summary>
   public class MessageContext : IMessageContext
   {
       public string UserName { get; set; }
       public DateTime LastActiveTime { get; set; }
       public List<IRequestMessageBase> RequestMessages { get; set; }
       public List<IResponseMessageBase> ResponseMessages { get; set; }

public object StorageData { get; set; }

public MessageContext()
       {
           /*
            * 注意:即使使用其他类实现IMessageContext,
            * 也务必在这里进行下面的初始化,尤其是设置当前时间,
            * 这个时间关系到及时从缓存中移除过期的消息,节约内存使用
            */
           RequestMessages = new List<IRequestMessageBase>();
           ResponseMessages = new List<IResponseMessageBase>();
           LastActiveTime = DateTime.Now;
       }
   }

上面的代码根据注释很好理解,需要说明一下的是StorageData。这是一个用于储存任何和用户上下文有关数据的容器,WeixinContext和IMessageContext没有对它进行任何引用,完全由开发者决定里面的内容(比如用户执行到哪一步、或某个比较重要的位置信息等等),类似于Session的作用。

来源:https://github.com/JeffreySu/WeiXinMPSDK/wiki/

标签:C#,微信,公众号,开发,用户上下文,WeixinContext,MessageContext
0
投稿

猜你喜欢

  • 在Winform和WPF中注册全局快捷键实现思路及代码

    2023-03-13 23:00:25
  • Android开发文件存储实例

    2021-10-13 17:27:01
  • C# task应用实例详解

    2023-01-22 05:23:53
  • 只需两步实现Eclipse+Maven快速构建第一个Spring Boot项目

    2023-08-03 23:47:43
  • Android DataBinding手把手入门教程

    2023-04-29 18:51:24
  • sqlite数据库的介绍与java操作sqlite的实例讲解

    2023-05-09 03:07:40
  • Java实现身份证号码验证源码示例分享

    2022-12-24 03:58:50
  • springboot使用log4j2异步日志提升性能的实现方式

    2021-05-31 16:54:55
  • Java和Ceylon对象的构造和验证

    2022-04-05 04:28:37
  • JavaTCP上传图片代码实例

    2022-02-08 19:05:18
  • C#图片查看器实现方法

    2021-06-17 16:50:03
  • C# 调用命令行执行Cmd命令的操作

    2022-08-03 10:43:26
  • C#分屏控件用法实例

    2022-02-04 20:01:57
  • 基于MapReduce实现决策树算法

    2023-10-20 16:05:40
  • C#实现语音播报功能

    2023-06-26 20:35:26
  • Springboot与Maven多环境配置的解决方案

    2023-11-29 08:53:58
  • java中File类的使用方法

    2023-09-11 11:49:55
  • Windows+Apache+resin配置

    2023-10-16 08:53:07
  • servlet之session简介_动力节点Java学院整理

    2023-07-07 00:51:07
  • Java stream sorted使用 Comparator 进行多字段排序的方法

    2022-07-26 05:02:13
  • asp之家 软件编程 m.aspxhome.com