Aperçu
En raison du mécanisme spécial de la plateforme publique WeChat, toutes les informations sont transmises par le serveur WeChat, de sorte que le serveur ne peut pas utiliser Session pour gérer le contexte de la session utilisateur.
A cet effet, le SDK Senparc.WeiXin.MP ajoute un module contextuel et l'intègre dans le MessageHandler.
WeixinContext
WeixinContext est un conteneur pour toutes les entités de contexte utilisateur unique (MessageContext) (provisoirement appelées contexte global). WeixinContext lui-même n'est pas une classe statique, ce qui signifie que vous pouvez créer plusieurs entités de contexte dans la même application.
En même temps, une instance statique de WeixinContext est placée dans MessageHandler
Ainsi, dans toute instance qui implémente MessageHandler
WeixinContext est utilisé pour enregistrer le contexte de l'utilisateur (MessageContext) et fournit une série de méthodes. Les principales méthodes incluent :
. ///
/// Réinitialiser tous les paramètres de contexte, tous les enregistrements seront effacés
...
}
Il s'agit d'exploiter le File d'attente TM, supprimez les informations expirées dans le temps et déplacez les derniers objets actifs vers la fin
///
/// Nom d'utilisateur ( OpenId)
>
///
/// Obtenir MessageContext
///
;/param>
// / True : Si l'utilisateur n'existe pas, créez une instance et renvoyez la dernière instance
/// False : L'utilisateur est stocké dans, puis renvoyez null
}
///
/// Récupérez le MessageContext, s'il n'existe pas, initialisez-en un à l'aide des informations requestMessage et renvoyez l'instance d'origine
// /
///
public TM GetMessageContext(IRequestMessageBase requestMessage)
///
///
///
public TM GetMessageContext( IResponseMessageBase réponseMessage)
/ //
}
///
/// Enregistrer les informations de réponse
/ //
/// Message de réponse
public void InsertMessage(IResponseMessageBase réponseMessage)
...
}
///
/// Obtenez les dernières données de la demande, si elles n'existent pas, renvoyez Null
///
/// < ;param name="userName">Username (OpenId)<
🎜> // /
/// Obtenez les dernières données de réponse, si elles n'existent pas, renvoyez Null
///
///
, , ; > }
WeixinContext a deux objets utilisés pour stocker le contexte utilisateur : MessageCollection et MessageQueue.
L'ensemble des éléments de ces deux objets se chevauchent, mais MessageQueue trie les éléments afin que le contexte le plus expiré soit traité dans le temps.
ExpireMinutes est utilisé pour définir la période de validité du contexte, la valeur par défaut est de 90 minutes. Vous pouvez définir un paramètre n'importe où dans le programme et il prendra effet immédiatement.
PS : La logique de suppression des données expirées dans MessageQueue fonctionne avec une efficacité extrêmement élevée. Il n'est pas nécessaire de prendre en compte les problèmes d'utilisation du processeur et de conflits d'objets (si le délai de vérification supplémentaire expire) pendant le développement régulier.
MessageContext
MessageContext est utilisé pour enregistrer les informations contextuelles d'un seul utilisateur et est stocké dans les objets MessageCollection et MessageQueue de WeixinContext. IMessageContext est défini comme suit :
/// <summary> /// 微信消息上下文(单个用户)接口 /// </summary> /// <typeparam name="TRequest">请求消息类型</typeparam> /// <typeparam name="TResponse">响应消息类型</typeparam> public interface IMessageContext<TRequest,TResponse> where TRequest : IRequestMessageBase where TResponse : IResponseMessageBase { /// <summary> /// 用户名(OpenID) /// </summary> string UserName { get; set; } /// <summary> /// 最后一次活动时间(用户主动发送Resquest请求的时间) /// </summary> DateTime LastActiveTime { get; set; } /// <summary> /// 接收消息记录 /// </summary> MessageContainer<TRequest> RequestMessages { get; set; } /// <summary> /// 响应消息记录 /// </summary> MessageContainer<TResponse> ResponseMessages { get; set; } /// <summary> /// 最大储存容量(分别针对RequestMessages和ResponseMessages) /// </summary> int MaxRecordCount { get; set; } /// <summary> /// 临时储存数据,如用户状态等,出于保持.net 3.5版本,这里暂不使用dynamic /// </summary> object StorageData { get; set; } /// <summary> /// 用于覆盖WeixinContext所设置的默认过期时间 /// </summary> Double? ExpireMinutes { get; set; } /// <summary> /// AppStore状态,系统属性,请勿操作 /// </summary> AppStoreState AppStoreState { get; set; } event EventHandler<WeixinContextRemovedEventArgs<TRequest, TResponse>> MessageContextRemoved; void OnRemoved(); }
Vous pouvez créer votre propre classe en fonction de vos besoins, implémenter cette interface et être utilisée par WeixinContext. Bien sûr, si vos besoins ne sont pas si particuliers et que vous êtes paresseux, le SDK fournit une implémentation MessageContext par défaut :
/// <summary> /// 微信消息上下文(单个用户) /// </summary> public class MessageContext<TRequest,TResponse>: IMessageContext<TRequest, TResponse> where TRequest : IRequestMessageBase where TResponse : IResponseMessageBase { private int _maxRecordCount; public string UserName { get; set; } public DateTime LastActiveTime { get; set; } public MessageContainer<TRequest> RequestMessages { get; set; } public MessageContainer<TResponse> ResponseMessages { get; set; } public int MaxRecordCount { get { return _maxRecordCount; } set { RequestMessages.MaxRecordCount = value; ResponseMessages.MaxRecordCount = value; _maxRecordCount = value; } } public object StorageData { get; set; } public Double? ExpireMinutes { get; set; } /// <summary> /// AppStore状态,系统属性,请勿操作 /// </summary> public AppStoreState AppStoreState { get; set; } public virtual event EventHandler<WeixinContextRemovedEventArgs<TRequest, TResponse>> MessageContextRemoved = null; /// <summary> /// 执行上下文被移除的事件 /// 注意:此事件不是实时触发的,而是等过期后任意一个人发过来的下一条消息执行之前触发。 /// </summary> /// <param name="e"></param> private void OnMessageContextRemoved(WeixinContextRemovedEventArgs<TRequest, TResponse> e) { EventHandler<WeixinContextRemovedEventArgs<TRequest, TResponse>> temp = MessageContextRemoved; if (temp != null) { temp(this, e); } } /// <summary> /// /// </summary> /// <param name="maxRecordCount">maxRecordCount如果小于等于0,则不限制</param> public MessageContext(/*MessageContainer<IRequestMessageBase> requestMessageContainer, MessageContainer<IResponseMessageBase> responseMessageContainer*/) { /* * 注意:即使使用其他类实现IMessageContext, * 也务必在这里进行下面的初始化,尤其是设置当前时间, * 这个时间关系到及时从缓存中移除过期的消息,节约内存使用 */ RequestMessages = new MessageContainer<TRequest>(MaxRecordCount); ResponseMessages = new MessageContainer<TResponse>(MaxRecordCount); LastActiveTime = DateTime.Now; } public virtual void OnRemoved() { var onRemovedArg = new WeixinContextRemovedEventArgs<TRequest, TResponse>(this); OnMessageContextRemoved(onRemovedArg); } }
Le code ci-dessus est facile à comprendre en fonction des commentaires. Données de stockage. Il s'agit d'un conteneur utilisé pour stocker toutes les données liées au contexte utilisateur. WeixinContext et IMessageContext n'y font aucune référence. Il appartient entièrement au développeur de déterminer le contenu (comme l'étape franchie par l'utilisateur ou une étape importante). informations de localisation, etc., etc.), similaire au rôle de Session.
La classe MessageContext
public class CustomMessageContext : MessageContext<IRequestMessageBase,IResponseMessageBase> { public CustomMessageContext() { 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 CustomMessageContext; if (messageContext == null) { return;//如果是正常的调用,messageContext不会为null } //TODO:这里根据需要执行消息过期时候的逻辑,下面的代码仅供参考 //Log.InfoFormat("{0}的消息上下文已过期",e.OpenId); } }
CustomMessageContext_MessageContextRemoved(. ) méthode ci-dessus Elle sera déclenchée lorsque le contexte d'un utilisateur sera effacé et vous pourrez ajouter le code dont vous avez besoin. De plus, vous pouvez également remplacer des méthodes telles que OnRemoved() dans l'accumulation ou ajouter d'autres attributs et méthodes.
Pour plus d'articles liés au développement de la plateforme publique WeChat : résolution des problèmes de contexte utilisateur (session), veuillez faire attention au site Web PHP chinois !