• 钉钉开发系列(四)获取JS票据


    钉钉的客户端开发和服务端有一个重要的区别,服务端只需要得到access_token就可以了,而客户端还需要进一步换取jsticket。所以我们要进行客户端的开发,第一步就是得到jsticket。又由于jsticket有7200秒的限制,而且每请求一次前面的就会失效,为此我们需要做一个缓存层来保存。

    首先我们来看缓存层的代码

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace DDSDK
    {
        /// <summary>
        /// 简易缓存
        /// </summary>
        public class SimpleCacheProvider : ICacheProvider
        {
            private static SimpleCacheProvider _instance = null;
            private readonly object _lockObj=new object();
            #region GetInstance
            /// <summary>
            /// 获取缓存实例
            /// </summary>
            /// <returns></returns>
            public static SimpleCacheProvider GetInstance()
            {
                if (_instance == null) lock(_lockObj){_instance =_instance?? new SimpleCacheProvider()};//使用单例模式以确保并发时实例始终是同一个
                return _instance;
            }
            #endregion
    
            private Dictionary<string, CacheItem> _caches;
    
            private SimpleCacheProvider()
            {
                this._caches = new Dictionary<string, CacheItem>();
            }
    
            #region GetCache
            /// <summary>
            /// 获取缓存
            /// </summary>
            /// <param name="key"></param>
            /// <returns></returns>
            public object GetCache(string key)
            {
                object obj = this._caches.ContainsKey(key) ? this._caches[key].Expired() ? null : this._caches[key].Value : null;
                return obj;
            }
    
            /// <summary>
            /// 获取缓存
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="key"></param>
            /// <returns></returns>
            public T GetCache<T>(String key)
            {
                object obj = GetCache(key);
                if (obj == null)
                {
                    return default(T);
                }
                T result = (T)obj;
                return result;
            }
            #endregion
    
            #region SetCache
            /// <summary>
            /// 设置缓存
            /// </summary>
            /// <param name="key"></param>
            /// <param name="value"></param>
            /// <param name="expire"></param>
            public void SetCache(string key, object value, int expire = 300)
            {
                this._caches[key] = new CacheItem(key, value, expire);
            }
            #endregion
        }
    }
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace DDSDK
    {
        /// <summary>
        /// 缓存接口
        /// </summary>
        interface ICacheProvider
        {
            /// <summary>
            /// 获取缓存
            /// </summary>
            /// <param name="key">缓存key</param>
            /// <returns>缓存对象或null,不存在或者过期返回null</returns>
            object GetCache(string key);
    
            /// <summary>
            /// 写入缓存
            /// </summary>
            /// <param name="key">缓存key</param>
            /// <param name="value">缓存值</param>
            /// <param name="expire">缓存有效期,单位为秒,默认300</param>
            void SetCache(string key, object value, int expire = 300);
        }
    }
    

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace DDSDK
    {
        /// <summary>
        /// 缓存项
        /// </summary>
        public class CacheItem
        {
    
            #region 属性
            private object _value;
            public object Value
            {
                get { return _value; }
                set { _value = value; }
            }
    
            private string _key;
            public string Key
            {
                get { return _key; }
                set { _key = value; }
            }
            #endregion
    
            #region 内部变量
            /// <summary>
            /// 插入时间
            /// </summary>
            private DateTime _insertTime;
            /// <summary>
            /// 过期时间
            /// </summary>
            private int _expire;
            #endregion
    
            #region 构造函数
            /// <summary>
            /// 构造函数
            /// </summary>
            /// <param name="key">缓存的KEY</param>
            /// <param name="value">缓存的VALUE</param>
            /// <param name="expire">缓存的过期时间</param>
            public CacheItem(string key, object value, int expire)
            {
                this._key = key;
                this._value = value;
                this._expire = expire;
                this._insertTime = DateTime.Now();
            }
            #endregion
    
            #region Expired
            /// <summary>
            /// 是否过期
            /// </summary>
            /// <returns></returns>
            public bool Expired()
            {
                return DateTime.Now() < this._insertTime.AddSeconds(_expire);
            }
            #endregion
        }
    }
    

    代码中最关键的是缓存的单例GetInstance,这样确保了全局的一致性。如果需要进一步强化,可以考虑使用lock来实现更结实的单例模式。

    下面我们来获取jsticket.

       #region FetchJSTicket Function  
            /// <summary>
            /// 获取JS票据
            /// </summary>
            /// <param name="url"></param>
            /// <returns></returns>
            public static JSTicket FetchJSTicket()
            {
                var cache = SimpleCacheProvider.GetInstance();
                var jsTicket = cache.GetCache<JSTicket>(ConstVars.CACHE_JS_TICKET_KEY);
                if (jsTicket == null||AccessToken.Begin.AddSeconds(ConstVars.CACHE_TIME) < DateTime.Now)//jsTicket为null表示不存在或过期,或AccessToken过期
                {
                    String apiurl = FormatApiUrlWithToken(Urls.get_jsapi_ticket);//该方法参看《钉钉开发系列(三)API的调用》
                    jsTicket = Analyze.Get<JSTicket>(apiurl);
                    cache.SetCache(ConstVars.CACHE_JS_TICKET_KEY, jsTicket, ConstVars.CACHE_TIME-500);//增加500的时间差以防与AccessToken错位过期
                }
                return jsTicket;
            }
            #endregion

    namespace DDSDK
    {
        /// <summary>
        /// JSAPI时用的票据
        /// </summary>
        public class JSTicket : ResultPackage
        {
            public string ticket { get; set; }
            public int expires_in { get; set; }
        }
    }

    调用FetchJsTicket就可以得到JS票据了,并且内部已经作了相应的缓存处理。

    欢迎打描左侧二维码打赏。

    转载请注明出处。

  • 相关阅读:
    centos pptp client 配置
    hadoop hdfs 权限修改
    cdh Host Monitor 启动失败
    cdh yarn 启动失败
    hive 存储
    docker修改默认存储位置
    centos新增磁盘
    zookeeper服务部署数量
    实时人群计算——设想
    docker容器多服务——Supervisor
  • 原文地址:https://www.cnblogs.com/sparkleDai/p/7604932.html
Copyright © 2020-2023  润新知