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

来源:互联网 发布:淘宝新手开直通车 编辑:程序博客网 时间:2024/06/12 01:05

钉钉的客户端开发和服务端有一个重要的区别,服务端只需要得到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    }}

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">代码中最关键的是缓存的单例GetInstance,这样确保了全局的一致性。如果需要进一步强化,可以考虑使用lock来实现更结实的单例模式。</span>

下面我们来获取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);                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票据了,并且内部已经作了相应的缓存处理。

转载请注明出处。

0 0