Maison > Applet WeChat > Développement WeChat > Développement de la plateforme publique WeChat : résoudre les problèmes de contexte utilisateur (session)

Développement de la plateforme publique WeChat : résoudre les problèmes de contexte utilisateur (session)

高洛峰
Libérer: 2017-02-27 13:08:18
original
3085 Les gens l'ont consulté

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, de sorte que le WeixinContext dans toutes les sous-classes dérivées de MessageHandler IMessageContext, y compris MessageContext déjà fourni dans le SDK).

Ainsi, dans toute instance qui implémente MessageHandler (comme MyMessageHandler), nous pouvons accéder à un objet dont le type et le nom sont WeixinContext.

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)
/// /// Récupérer le MessageContext , s'il n'existe pas, initialisez-en un à l'aide des informations requestMessage et renvoyez l'instance d'origine
///
///
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();
}
Copier après la connexion

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);
    }
}
Copier après la connexion

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 ci-dessus a fourni des méthodes courantes de traitement des messages relativement complètes et peut être utilisée directement. Si vous avez des besoins plus particuliers et devez personnaliser MessageContext, il est recommandé d'utiliser cette classe comme classe de base pour effectuer les réécritures nécessaires. Par exemple, ce qui suit est une classe de contexte personnalisée :

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);
    }
}
Copier après la connexion

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 !

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal