WeChat 공개 플랫폼 개발: 사용자 컨텍스트(세션) 문제 해결

高洛峰
풀어 주다: 2017-02-27 13:08:18
원래의
3017명이 탐색했습니다.

개요

WeChat 공개 플랫폼의 특별한 메커니즘으로 인해 모든 정보는 WeChat 서버에서 전달되므로 서버는 Session을 사용하여 사용자 세션의 컨텍스트를 관리할 수 없습니다.

이를 위해 Senparc.WeiXin.MP SDK는 컨텍스트 모듈을 추가하고 이를 MessageHandler에 통합합니다.

WeixinContext

WeixinContext는 모든 단일 사용자 컨텍스트(MessageContext) 엔터티(가칭 전역 컨텍스트라고 함)에 대한 컨테이너입니다. WeixinContext 자체는 정적 클래스가 아닙니다. 즉, 동일한 애플리케이션에서 여러 컨텍스트 엔터티를 만들 수 있습니다.

동시에 정적 WeixinContext 인스턴스가 MessageHandler에 배치되므로 모든 프로젝트의 MessageHandler에서 파생된 모든 하위 클래스의 WeixinContext는 고유하고 전역적입니다(참고: TM은 MessageHandler IMessageContext(SDK에서 이미 제공되는 MessageContext 포함).

따라서 MessageHandler(예: MyMessageHandler)를 구현하는 모든 인스턴스에서 유형과 이름이 WeixinContext인 개체에 액세스할 수 있습니다.

WeixinContext는 사용자의 컨텍스트(MessageContext)를 저장하는 데 사용되며 주요 메서드는 다음과 같습니다.

///


/// 모든 컨텍스트 매개변수를 재설정하면 모든 기록이 삭제됩니다.

...
}

TM 대기열, 만료된 정보를 시간 내에 제거하고 최신 활성 개체를 끝으로 이동
///

/// 사용자 이름( OpenId)
                                                                                             >
///
/// MessageContext 가져오기
///

;/param>
// / True: 사용자가 존재하지 않으면 인스턴스를 생성하고 최신 인스턴스를 반환합니다.
/// False: 사용자가 저장된 후 null을 반환합니다
                                                                                                                                   }


///
/// MessageContext를 가져오고, 존재하지 않는 경우 requestMessage 정보를 사용하여 초기화하고 원래 인스턴스를 반환합니다.
// /

///
public TM GetMessageContext(IRequestMessageBase requestMessage)
{
...
}

/// /// MessageContext를 가져오고, 존재하지 않으면 requestMessage 정보를 사용하여 초기화하고 원래 인스턴스를 반환합니다.
///
/// <반환>
공개 TM GetMessageContext(IResponseMessageBase responseMessage)
                                    
/ //
       > > }

/// < ;summary>
/// 응답 정보 기록
///
/// 응답 메시지
public void InsertMessage(IResponseMessageBase responseMessage)
...
}

///
/// 최신 요청 데이터를 가져오고, 없으면 Null을 반환합니다
///

/// 사용자 이름(OpenId)< /param>
                                                    // // 최신 응답 데이터를 가져오고, 존재하지 않으면 Null을 반환합니다.
///
///
                                                                         , ,                                  > }

WeixinContext에는 사용자 컨텍스트를 저장하는 데 사용되는 두 개의 개체, 즉 MessageCollection과 MessageQueue가 있습니다.

이 두 개체의 요소 집합은 겹치지만 MessageQueue는 만료된 최상위 컨텍스트가 시간 내에 처리되도록 요소를 정렬합니다.

ExpireMinutes는 컨텍스트 시간 유효 기간을 정의하는 데 사용되며 기본값은 90분입니다. 프로그램 어디에서나 매개변수를 설정할 수 있으며 즉시 적용됩니다.

PS: MessageQueue에서 만료된 데이터를 삭제하는 논리는 매우 높은 효율성으로 작동합니다. 일반 개발 중에는 CPU 사용량 및 개체 충돌 문제(추가 확인 시간 초과 여부)를 고려할 필요가 없습니다.

MessageContext

MessageContext는 단일 사용자의 컨텍스트 정보를 저장하는 데 사용되며 WeixinContext의 MessageCollection 및 MessageQueue 개체에 저장됩니다. IMessageContext는 다음과 같이 정의됩니다.

/// <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();
}
로그인 후 복사

필요에 따라 자신만의 클래스를 만들고, 이 인터페이스를 구현하고, WeixinContext에서 사용할 수 있습니다. 물론 요구 사항이 그다지 특별하지 않고 게으른 경우 SDK는 기본 MessageContext 구현을 제공합니다.

/// <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);
    }
}
로그인 후 복사

위 코드는 주석을 기반으로 이해하기 쉽습니다. 설명해야 할 것은 StorageData입니다. 이는 사용자 컨텍스트와 관련된 데이터를 저장하는 데 사용되는 컨테이너입니다. WeixinContext 및 IMessageContext에는 이에 대한 참조가 없습니다. 콘텐츠(예: 사용자가 수행한 단계 또는 일부 중요한 사항)를 결정하는 것은 전적으로 개발자의 몫입니다. 위치 정보 등), Session의 역할과 유사합니다.

위의 MessageContext 클래스는 비교적 완전한 공통 메시지 처리 방법을 제공하며 직접 사용할 수 있습니다. 더 특별한 요구사항이 있고 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( ) 메서드는 사용자의 컨텍스트가 지워지면 트리거되며 필요한 코드를 추가할 수 있습니다. 또한 누적되는 OnRemoved()와 같은 메서드를 재정의하거나 다른 특성 및 메서드를 추가할 수도 있습니다.

WeChat 공개 플랫폼 개발과 관련된 더 많은 기사: 사용자 컨텍스트(세션) 문제 해결을 보려면 PHP 중국어 웹사이트를 주목하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!