钉钉开发系列(四)获取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;
}
#endregionnamespace DDSDK
{
/// <summary>
/// JSAPI时用的票据
/// </summary>
public class JSTicket : ResultPackage
{
public string ticket { get; set; }
public int expires_in { get; set; }
}
}调用FetchJsTicket就可以得到JS票据了,并且内部已经作了相应的缓存处理。
欢迎打描左侧二维码打赏。
转载请注明出处。

浙公网安备 33010602011771号