你的位置:首页 > ASP.net教程

[ASP.net教程]C#链接阿里云OCS

一、阿里云OCS简单介绍

  阿里云OCS兼容Memcached,因为OCS就相当于Memcached的服务器端,我们代码只是当作客户端,链接上服务器端就行了。阿里云OCS介绍详情见 http://www.aliyun.com/product/ocs?spm=5176.2020520107.0.0.s2zgFk#Help 。

 

二、C#客户端链接OCS

  1.阿里云文档上介绍的是用Enyim.Caching去链接OCS。那我们项目中就用nuget去下载Enyim.Caching包。nuget搜索Enyim,搜索到的结果如下图,第一个是nolog版本的,第二个是带log的,随便一个都可以。

  nuget搜索结果如下:

  

  2.安装成功以后,再链接OCS,写个初始化memcached的代码,代码如下。

 1 using Enyim.Caching; 2 using Enyim.Caching.Configuration; 3 using Enyim.Caching.Memcached; 4 using System; 5 using System.Collections.Generic; 6 using System.Linq; 7 using System.Net; 8 using System.Text; 9 using System.Threading.Tasks;10 11 namespace OCS12 {13   public class MemCached14   {15     private static MemcachedClient MemClient;16 17     static readonly object padlock = new object();18     //线程安全的单例模式19     public static MemcachedClient getInstance(string hostName,string userName,string password)20     {21       if (MemClient == null)22       {23         lock (padlock)24         {25           if (MemClient == null)26           {27             MemClientInit(hostName,userName,password);28           }29         }30       }31       return MemClient;32     }33 34     static void MemClientInit(string hostName,string userName,string password)35     {36       try37       {38         //初始化缓存39         MemcachedClientConfiguration memConfig = new MemcachedClientConfiguration();40         IPAddress newaddress = IPAddress.Parse(Dns.GetHostEntry(hostName).AddressList[0].ToString());41         IPEndPoint ipEndPoint = new IPEndPoint(newaddress, 11211);42 43         // 配置文件 - ip44         memConfig.Servers.Add(ipEndPoint);45         // 配置文件 - 协议46         memConfig.Protocol = MemcachedProtocol.Binary;47         // 配置文件-权限48         memConfig.Authentication.Type = typeof(PlainTextAuthenticator);49         memConfig.Authentication.Parameters["zone"] = "";50         memConfig.Authentication.Parameters["userName"] = userName;51         memConfig.Authentication.Parameters["password"] = password;52         //下面请根据实例的最大连接数进行设置53         memConfig.SocketPool.MinPoolSize = 5;54         memConfig.SocketPool.MaxPoolSize = 200;55         MemClient = new MemcachedClient(memConfig);56       }57       catch (Exception)58       {59         MemClient = null;60       }61     }62   }63 }

  3.再写个服务去调用上面的初始化代码,创建MemcachedClient的实例去调用客户端代码。下面代码中的构造函数中的_setting.HostAddress, _setting.AccessId, _setting.AccessKey分别对应的是,OCS的链接地址,链接密码和OCS的实例ID。

 1 using Enyim.Caching; 2 using Enyim.Caching.Memcached; 3 using Enyim.Caching.Memcached.Results; 4 using System; 5 using System.Collections.Generic; 6 using System.Linq; 7 using System.Text; 8 using System.Text.RegularExpressions; 9 using System.Threading.Tasks; 10 using System.Web.Script.Serialization; 11 using Zupo.Core.Caching; 12 using ServiceStack.Text; 13 using Newtonsoft.Json; 14  15 namespace OCS 16 { 17   public class OCSService 18   { 19     IOCSSetting _setting; 20  21     private MemcachedClient client; 22  23     public OCSService(IOCSSetting setting) 24     { 25       this._setting = setting; 26       this.client = MemCached.getInstance(_setting.HostAddress, _setting.AccessId, _setting.AccessKey); 27     } 28  29     /// <summary> 30     /// 是否链接上服务器 31     /// </summary> 32     protected bool LinkServer 33     { 34       get 35       { 36         return client == null ? false : true; 37       } 38     } 39  40     protected IGetOperationResult ExecuteGet(string key) 41     { 42       return client.ExecuteGet(key); 43     } 44  45     /// <summary> 46     /// 根据key获得缓存 47     /// </summary> 48     /// <param name="key"></param> 49     /// <returns></returns> 50     protected object Get(string key) 51     { 52       return client.Get(key); 53     } 54  55     /// <summary> 56     /// 根据key获得缓存 泛型方法 57     /// </summary> 58     /// <typeparam name="T"></typeparam> 59     /// <param name="key"></param> 60     /// <returns></returns> 61     protected T Get<T>(string key) 62     { 63       try 64       { 65         //JavaScriptSerializer jsonSerializer = new JavaScriptSerializer(); 66         //string objectStr = client.Get(key).ToString(); 67         var obj = client.Get(key); 68         if (obj != null) 69         { 70           return JsonConvert.DeserializeObject<T>(obj.ToString()); 71         } 72         return default(T); 73         //return objectStr.FromJson<T>(); 74       } 75       catch (Exception) 76       { 77         this.Remove(key); 78         return default(T); 79       } 80     } 81  82     /// <summary> 83     /// 根据key获得缓存 泛型方法 84     /// </summary> 85     /// <typeparam name="T"></typeparam> 86     /// <param name="key"></param> 87     /// <returns></returns> 88     protected List<T> GetList<T>(string key) 89     { 90       var objectStr = client.Get(key).ToString(); 91  92       //return objectStr.FromJson<List<T>>(); 93       return JsonConvert.DeserializeObject<List<T>>(objectStr); 94     } 95  96     /// <summary> 97     /// 根据数组key获得数据 IDictionary 98     /// </summary> 99     /// <param name="keys"></param>100     /// <returns></returns>101     protected IDictionary<string, object> GetByKeys(string[] keys)102     {103       return client.Get(keys);104     }105 106     /// <summary>107     /// 该key值缓存是否存在108     /// </summary>109     /// <param name="key"></param>110     /// <returns></returns>111     public bool Contains(string key)112     {113       object value;114 115       return client.TryGet(key, out value);116     }117 118     /// <summary>119     /// 存储,有的话直接覆盖120     /// </summary>121     /// <param name="key"></param>122     /// <param name="value"></param>123     /// <returns></returns>124     protected bool Set(string key, object value)125     {126       return client.Store(StoreMode.Set, key, value);127     }128 129     /// <summary>130     /// 存储,有的话直接覆盖131     /// </summary>132     /// <param name="key"></param>133     /// <param name="value"></param>134     /// <returns></returns>135     protected bool Set<T>(string key, T value)136     {137       try138       {139         //执行序列化140         //string objectStr = value.ToJson();141         string objectStr = JsonConvert.SerializeObject(value, Formatting.Indented, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore });142         return client.Store(StoreMode.Set, key, objectStr);143       }144       catch(Exception)145       {146         return false;147       }148       149     }150 151     /// <summary>152     /// 存储,有的话直接覆盖153     /// </summary>154     /// <param name="key"></param>155     /// <param name="value"></param>156     /// <returns></returns>157     protected bool Set<T>(string key, List<T> value)158     {159       //执行序列化160       //string objectStr = value.ToJson();161       string objectStr = JsonConvert.SerializeObject(value, Formatting.Indented, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore });162       return client.Store(StoreMode.Set, key, objectStr);163     }164 165     /// <summary>166     /// 存储,有的话直接覆盖167     /// </summary>168     /// <param name="key"></param>169     /// <param name="value"></param>170     /// <param name="expire">失效时间:TimeSpan</param>171     /// <returns></returns>172     protected bool SetExpires(string key, object value, TimeSpan expire)173     {174       try175       {176         //string objectStr = value.ToJson();177         string objectStr = JsonConvert.SerializeObject(value, Formatting.Indented, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore });178         return client.Store(StoreMode.Set, key, objectStr, expire);179       }180       catch(Exception)181       {182         return false;183       }184       185     }186 187     /// <summary>188     /// 存储,有的话直接覆盖189     /// </summary>190     /// <param name="key"></param>191     /// <param name="value"></param>192     /// <param name="expire">失效时间:TimeSpan</param>193     /// <returns></returns>194     protected bool SetExpires<T>(string key, T value, TimeSpan expire)195     {196       //执行序列化197       //string objectStr = value.ToJson();198       string objectStr = JsonConvert.SerializeObject(value, Formatting.Indented, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore });199       return client.Store(StoreMode.Set, key, objectStr, expire);200     }201 202     /// <summary>203     /// 删除cached204     /// </summary>205     /// <param name="key"></param>206     /// <returns></returns>207     public void Remove(string key)208     {209       client.Remove(key);210     }211 212     /// <summary>213     /// Removes items by pattern214     /// 该方法未实现215     /// </summary>216     /// <param name="pattern">pattern</param>217     public virtual void RemoveByPattern(string pattern)218     {219       var regex = new Regex(pattern, RegexOptions.Singleline | RegexOptions.Compiled | RegexOptions.IgnoreCase);220       //var keysToRemove = new List<String>();221 222       //var allkeys = client.223       //foreach (var key in allkeys)224       //  if (regex.IsMatch(key))225       //    keysToRemove.Add(key);226 227       //foreach (string key in keysToRemove)228       //{229       //  Remove(key);230       //}231     }232 233     /// <summary>234     /// 清空ocs缓存235     /// </summary>236     /// <returns></returns>237     public void Clear()238     {239       client.FlushAll();240     }241   }242 }

MemcachedClient


三、使用注意点

  因为OCS只支持key/value的格式进行存储,所以我项目中先运用了Newtonsoft.Json去先对对象序列化,再存入到OCS上,读取的时候再反序列化读取。代码如下:

 1 /// <summary> 2     /// 存储,有的话直接覆盖 3     /// </summary> 4     /// <param name="key"></param> 5     /// <param name="value"></param> 6     /// <returns></returns> 7     protected bool Set<T>(string key, T value) 8     { 9       try10       {11         //执行序列化12         string objectStr = JsonConvert.SerializeObject(value, Formatting.Indented, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore });13         return client.Store(StoreMode.Set, key, objectStr);14       }15       catch(Exception)16       {17         return false;18       }19       20     }

View Code

代码中设置了JsonSerializerSettings,因为项目用的是EF,一些对象里面的属性可能是另外一个对象还有是一些死循环的属性,所以数据量会比较大,直接执行序列化会内存溢出的,所以要在对象里面不需要序列化的属性上加上[JsonIgnore],忽略此属性或字段序列化。
那么反序列化获取数据代码如下:

 1 /// <summary> 2     /// 根据key获得缓存 泛型方法 3     /// </summary> 4     /// <typeparam name="T"></typeparam> 5     /// <param name="key"></param> 6     /// <returns></returns> 7     protected T Get<T>(string key) 8     { 9       try10       {11         var obj = client.Get(key);12         if (obj != null)13         {14           return JsonConvert.DeserializeObject<T>(obj.ToString());15         }16         return default(T);17       }18       catch (Exception)19       {20         this.Remove(key);21         return default(T);22       }23     }

View Code