1. using StackExchange.Redis;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using System.Linq;
  6. using System.Net;
  7. using System.Runtime.Serialization.Formatters.Binary;
  8. using System.Text;
  9. using System.Threading.Tasks;
  10.  
  11. namespace WindowsFormsApplication1
  12. {
  13. public static class RedisHelper
  14. {
  15. private static string Constr = "";
  16.  
  17. private static object _locker = new Object();
  18. private static ConnectionMultiplexer _instance = null;
  19.  
  20. /// <summary>
  21. /// 使用一个静态属性来返回已连接的实例,如下列中所示。这样,一旦 ConnectionMultiplexer 断开连接,便可以初始化新的连接实例。
  22. /// </summary>
  23. public static ConnectionMultiplexer Instance
  24. {
  25. get
  26. {
  27. if (Constr.Length == )
  28. {
  29. throw new Exception("连接字符串未设置!");
  30. }
  31. if (_instance == null)
  32. {
  33. lock (_locker)
  34. {
  35. if (_instance == null || !_instance.IsConnected)
  36. {
  37. _instance = ConnectionMultiplexer.Connect(Constr);
  38. }
  39. }
  40. }
  41. //注册如下事件
  42. _instance.ConnectionFailed += MuxerConnectionFailed;
  43. _instance.ConnectionRestored += MuxerConnectionRestored;
  44. _instance.ErrorMessage += MuxerErrorMessage;
  45. _instance.ConfigurationChanged += MuxerConfigurationChanged;
  46. _instance.HashSlotMoved += MuxerHashSlotMoved;
  47. _instance.InternalError += MuxerInternalError;
  48. return _instance;
  49. }
  50. }
  51.  
  52. static RedisHelper()
  53. {
  54. }
  55.  
  56. public static void SetCon(string config)
  57. {
  58. Constr = config;
  59. }
  60.  
  61. /// <summary>
  62. ///
  63. /// </summary>
  64. /// <returns></returns>
  65. public static IDatabase GetDatabase()
  66. {
  67. return Instance.GetDatabase();
  68. }
  69.  
  70. /// <summary>
  71. /// 这里的 MergeKey 用来拼接 Key 的前缀,具体不同的业务模块使用不同的前缀。
  72. /// </summary>
  73. /// <param name="key"></param>
  74. /// <returns></returns>
  75. private static string MergeKey(string key)
  76. {
  77. return key;
  78. //return BaseSystemInfo.SystemCode + key;
  79. }
  80.  
  81. /// <summary>
  82. /// 根据key获取缓存对象
  83. /// </summary>
  84. /// <typeparam name="T"></typeparam>
  85. /// <param name="key"></param>
  86. /// <returns></returns>
  87. public static T Get<T>(string key)
  88. {
  89. key = MergeKey(key);
  90. return Deserialize<T>(GetDatabase().StringGet(key));
  91. }
  92.  
  93. /// <summary>
  94. /// 根据key获取缓存对象
  95. /// </summary>
  96. /// <param name="key"></param>
  97. /// <returns></returns>
  98. public static object Get(string key)
  99. {
  100. key = MergeKey(key);
  101. return Deserialize<object>(GetDatabase().StringGet(key));
  102. }
  103.  
  104. /// <summary>
  105. /// 设置缓存
  106. /// </summary>
  107. /// <param name="key"></param>
  108. /// <param name="value"></param>
  109. /// <param name="expireMinutes"></param>
  110. public static void Set(string key, object value, int expireMinutes = )
  111. {
  112. key = MergeKey(key);
  113. if (expireMinutes > )
  114. {
  115. GetDatabase().StringSet(key, Serialize(value), TimeSpan.FromMinutes(expireMinutes));
  116. }
  117. else
  118. {
  119. GetDatabase().StringSet(key, Serialize(value));
  120. }
  121.  
  122. }
  123.  
  124. /// <summary>
  125. /// 判断在缓存中是否存在该key的缓存数据
  126. /// </summary>
  127. /// <param name="key"></param>
  128. /// <returns></returns>
  129. public static bool Exists(string key)
  130. {
  131. key = MergeKey(key);
  132. return GetDatabase().KeyExists(key); //可直接调用
  133. }
  134.  
  135. /// <summary>
  136. /// 移除指定key的缓存
  137. /// </summary>
  138. /// <param name="key"></param>
  139. /// <returns></returns>
  140. public static bool Remove(string key)
  141. {
  142. key = MergeKey(key);
  143. return GetDatabase().KeyDelete(key);
  144. }
  145.  
  146. /// <summary>
  147. /// 异步设置
  148. /// </summary>
  149. /// <param name="key"></param>
  150. /// <param name="value"></param>
  151. public static async Task SetAsync(string key, object value)
  152. {
  153. key = MergeKey(key);
  154. await GetDatabase().StringSetAsync(key, Serialize(value));
  155. }
  156.  
  157. /// <summary>
  158. /// 根据key获取缓存对象
  159. /// </summary>
  160. /// <param name="key"></param>
  161. /// <returns></returns>
  162. public static async Task<object> GetAsync(string key)
  163. {
  164. key = MergeKey(key);
  165. object value = await GetDatabase().StringGetAsync(key);
  166. return value;
  167. }
  168.  
  169. /// <summary>
  170. /// 实现递增
  171. /// </summary>
  172. /// <param name="key"></param>
  173. /// <returns></returns>
  174. public static long Increment(string key)
  175. {
  176. key = MergeKey(key);
  177. //三种命令模式
  178. //Sync,同步模式会直接阻塞调用者,但是显然不会阻塞其他线程。
  179. //Async,异步模式直接走的是Task模型。
  180. //Fire - and - Forget,就是发送命令,然后完全不关心最终什么时候完成命令操作。
  181. //即发即弃:通过配置 CommandFlags 来实现即发即弃功能,在该实例中该方法会立即返回,如果是string则返回null 如果是int则返回0.这个操作将会继续在后台运行,一个典型的用法页面计数器的实现:
  182. return GetDatabase().StringIncrement(key, flags: CommandFlags.FireAndForget);
  183. }
  184.  
  185. /// <summary>
  186. /// 实现递减
  187. /// </summary>
  188. /// <param name="key"></param>
  189. /// <param name="value"></param>
  190. /// <returns></returns>
  191. public static long Decrement(string key, string value)
  192. {
  193. key = MergeKey(key);
  194. return GetDatabase().HashDecrement(key, value, flags: CommandFlags.FireAndForget);
  195. }
  196.  
  197. /// <summary>
  198. /// 序列化对象
  199. /// </summary>
  200. /// <param name="o"></param>
  201. /// <returns></returns>
  202. private static byte[] Serialize(object o)
  203. {
  204. if (o == null)
  205. {
  206. return null;
  207. }
  208. BinaryFormatter binaryFormatter = new BinaryFormatter();
  209. using (MemoryStream memoryStream = new MemoryStream())
  210. {
  211. binaryFormatter.Serialize(memoryStream, o);
  212. byte[] objectDataAsStream = memoryStream.ToArray();
  213. return objectDataAsStream;
  214. }
  215. }
  216.  
  217. /// <summary>
  218. /// 反序列化对象
  219. /// </summary>
  220. /// <typeparam name="T"></typeparam>
  221. /// <param name="stream"></param>
  222. /// <returns></returns>
  223. private static T Deserialize<T>(byte[] stream)
  224. {
  225. if (stream == null)
  226. {
  227. return default(T);
  228. }
  229. BinaryFormatter binaryFormatter = new BinaryFormatter();
  230. using (MemoryStream memoryStream = new MemoryStream(stream))
  231. {
  232. T result = (T)binaryFormatter.Deserialize(memoryStream);
  233. return result;
  234. }
  235. }
  236.  
  237. /// <summary>
  238. /// 配置更改时
  239. /// </summary>
  240. /// <param name="sender"></param>
  241. /// <param name="e"></param>
  242. private static void MuxerConfigurationChanged(object sender, EndPointEventArgs e)
  243. {
  244. //LogHelper.SafeLogMessage("Configuration changed: " + e.EndPoint);
  245. }
  246.  
  247. /// <summary>
  248. /// 发生错误时
  249. /// </summary>
  250. /// <param name="sender"></param>
  251. /// <param name="e"></param>
  252. private static void MuxerErrorMessage(object sender, RedisErrorEventArgs e)
  253. {
  254. //LogHelper.SafeLogMessage("ErrorMessage: " + e.Message);
  255. }
  256.  
  257. /// <summary>
  258. /// 重新建立连接之前的错误
  259. /// </summary>
  260. /// <param name="sender"></param>
  261. /// <param name="e"></param>
  262. private static void MuxerConnectionRestored(object sender, ConnectionFailedEventArgs e)
  263. {
  264. //LogHelper.SafeLogMessage("ConnectionRestored: " + e.EndPoint);
  265. }
  266.  
  267. /// <summary>
  268. /// 连接失败 , 如果重新连接成功你将不会收到这个通知
  269. /// </summary>
  270. /// <param name="sender"></param>
  271. /// <param name="e"></param>
  272. private static void MuxerConnectionFailed(object sender, ConnectionFailedEventArgs e)
  273. {
  274. //LogHelper.SafeLogMessage("重新连接:Endpoint failed: " + e.EndPoint + ", " + e.FailureType +(e.Exception == null ? "" : (", " + e.Exception.Message)));
  275. }
  276.  
  277. /// <summary>
  278. /// 更改集群
  279. /// </summary>
  280. /// <param name="sender"></param>
  281. /// <param name="e"></param>
  282. private static void MuxerHashSlotMoved(object sender, HashSlotMovedEventArgs e)
  283. {
  284. //LogHelper.SafeLogMessage("HashSlotMoved:NewEndPoint" + e.NewEndPoint + ", OldEndPoint" + e.OldEndPoint);
  285. }
  286.  
  287. /// <summary>
  288. /// redis类库错误
  289. /// </summary>
  290. /// <param name="sender"></param>
  291. /// <param name="e"></param>
  292. private static void MuxerInternalError(object sender, InternalErrorEventArgs e)
  293. {
  294. //LogHelper.SafeLogMessage("InternalError:Message" + e.Exception.Message);
  295. }
  296.  
  297. //场景不一样,选择的模式便会不一样,大家可以按照自己系统架构情况合理选择长连接还是Lazy。
  298. //建立连接后,通过调用ConnectionMultiplexer.GetDatabase 方法返回对 Redis Cache 数据库的引用。从 GetDatabase 方法返回的对象是一个轻量级直通对象,不需要进行存储。
  299.  
  300. /// <summary>
  301. /// 使用的是Lazy,在真正需要连接时创建连接。
  302. /// 延迟加载技术
  303. /// 微软azure中的配置 连接模板
  304. /// </summary>
  305. //private static Lazy<ConnectionMultiplexer> lazyConnection = new Lazy<ConnectionMultiplexer>(() =>
  306. //{
  307. // //var options = ConfigurationOptions.Parse(constr);
  308. // ////options.ClientName = GetAppName(); // only known at runtime
  309. // //options.AllowAdmin = true;
  310. // //return ConnectionMultiplexer.Connect(options);
  311. // ConnectionMultiplexer muxer = ConnectionMultiplexer.Connect(Coonstr);
  312. // muxer.ConnectionFailed += MuxerConnectionFailed;
  313. // muxer.ConnectionRestored += MuxerConnectionRestored;
  314. // muxer.ErrorMessage += MuxerErrorMessage;
  315. // muxer.ConfigurationChanged += MuxerConfigurationChanged;
  316. // muxer.HashSlotMoved += MuxerHashSlotMoved;
  317. // muxer.InternalError += MuxerInternalError;
  318. // return muxer;
  319. //});
  320.  
  321. #region 当作消息代理中间件使用 一般使用更专业的消息队列来处理这种业务场景
  322.  
  323. /// <summary>
  324. /// 当作消息代理中间件使用
  325. /// 消息组建中,重要的概念便是生产者,消费者,消息中间件。
  326. /// </summary>
  327. /// <param name="channel"></param>
  328. /// <param name="message"></param>
  329. /// <returns></returns>
  330. public static long Publish(string channel, string message)
  331. {
  332. ISubscriber sub = Instance.GetSubscriber();
  333. //return sub.Publish("messages", "hello");
  334. return sub.Publish(channel, message);
  335. }
  336.  
  337. /// <summary>
  338. /// 在消费者端得到该消息并输出
  339. /// </summary>
  340. /// <param name="channelFrom"></param>
  341. /// <returns></returns>
  342. public static void Subscribe(string channelFrom)
  343. {
  344. ISubscriber sub = Instance.GetSubscriber();
  345. sub.Subscribe(channelFrom, (channel, message) =>
  346. {
  347. Console.WriteLine((string)message);
  348. });
  349. }
  350.  
  351. #endregion
  352.  
  353. /// <summary>
  354. /// GetServer方法会接收一个EndPoint类或者一个唯一标识一台服务器的键值对
  355. /// 有时候需要为单个服务器指定特定的命令
  356. /// 使用IServer可以使用所有的shell命令,比如:
  357. /// DateTime lastSave = server.LastSave();
  358. /// ClientInfo[] clients = server.ClientList();
  359. /// 如果报错在连接字符串后加 ,allowAdmin=true;
  360. /// </summary>
  361. /// <returns></returns>
  362. public static IServer GetServer(string host, int port)
  363. {
  364. IServer server = Instance.GetServer(host, port);
  365. return server;
  366. }
  367.  
  368. /// <summary>
  369. /// 获取全部终结点
  370. /// </summary>
  371. /// <returns></returns>
  372. public static EndPoint[] GetEndPoints()
  373. {
  374. EndPoint[] endpoints = Instance.GetEndPoints();
  375. return endpoints;
  376. }
  377. }

RedisHelper Redis帮助类的更多相关文章

  1. Java的redis 操作类-优化通用版本

    java操作redis多节点处理方式;http://blog.itpub.net/29254281/viewspace-1188644/首先maven引入依赖包 <dependency> ...

  2. .net core下Redis帮助类

      0.引入.net core环境下Redis的NuGet包,StackExchange.Redis,现目前最新的2.0.519. 帮助类Code: using System; using Syste ...

  3. c#--Redis帮助类

    最近一直在忙公司的一下项目,也没有太多时间写,所以就分享出所用redis帮助类 using Newtonsoft.Json; using StackExchange.Redis; using Syst ...

  4. StackExchange.Redis帮助类解决方案RedisRepository封装(基础配置)

    本文版权归博客园和作者吴双本人共同所有,转载和爬虫,请注明原文地址.http://www.cnblogs.com/tdws/p/5815735.html 写在前面 这不是教程,分享而已,也欢迎园友们多 ...

  5. php的redis 操作类,适用于单台或多台、多组redis服务器操作

    redis 操作类,包括单台或多台.多组redis服务器操作,适用于业务复杂.高性能要求的 php web 应用. redis.php: <?php /* redis 操作类,适用于单台或多台. ...

  6. Redis操作Hash工具类封装,Redis工具类封装

    Redis操作Hash工具类封装,Redis工具类封装 >>>>>>>>>>>>>>>>>> ...

  7. Redis操作字符串工具类封装,Redis工具类封装

    Redis操作字符串工具类封装,Redis工具类封装 >>>>>>>>>>>>>>>>>>& ...

  8. 自己封装的C#操作redis公共类

    关于C#操作redis公共类,网上有很多版本,每个版本我都看了,发觉还是不够完美,都存在一个问题,只能操作单一的缓存数据库 redis指令支持上,这里可以自己去扩展,下面分享下我近期封装的一个redi ...

  9. 设计模式之PHP项目应用——单例模式设计Memcache和Redis操作类

    1 单例模式简单介绍 单例模式是一种经常使用的软件设计模式. 在它的核心结构中仅仅包括一个被称为单例类的特殊类. 通过单例模式能够保证系统中一个类仅仅有一个实例并且该实例易于外界訪问.从而方便对实例个 ...

随机推荐

  1. oracle执行计划(一)----概述

    (1)什么是执行计划SQL是一种傻瓜式语言,每一个条件就是一个需求,访问的顺序不同就形成了不同的执行计划.Oracle必须做出选择,一次只能有一种访问路径.一个访问路径就是一个执行计划. (2)执行计 ...

  2. SQL与NoSQL区别--商业SQL数据库衰落--oracle面临困境

    转自:商用数据库之死:Oracle 面临困境 这二十年来,商业数据库市场仍然是 IT 行业最稳定.最具黏性的领域之一,Oracle.IBM 和微软三家厂商瓜分了 80% 的份额.然而,我们认为这个领域 ...

  3. Web数据库架构

    Web服务器的基本操作如图下图所示: 这个系统由两个对象组成:一个Web浏览器和一个Web服务器.它们之间需要通信连接.Web浏览器向服务器发出请求.服务器返回一个响应.这种架构非常适合服务器发布静态 ...

  4. Centos7安装配置Nginx_笔记

    从Nginx官方网站下载稳定的主要分支版本.然后解压开来. 在Linux中需要使用编译工具编译安装Nginx. 首先安装“Development Tools”工具,包含了所有编译Nginx所需的依赖工 ...

  5. Python中单引号、双引号、三引号的区别

    在学习python中的sqlite时发现实例的语句创建表时是用的三个单引号,但其他的表操作语句都是双引号,就不明白,于是搜了一下,在此做一下笔记. import sqlite3 conn = sqli ...

  6. Linux中在vim/vi模式下对文本的查找和替换

    查找: 1.vim  filename  进入一般模式下 2.查找和替换方法 /word    向下查找word 的字符串  例如  /chengtingting   向下查找字符chengtingt ...

  7. HBase数据结构

    1 RowKey 与nosql数据库们一样,RowKey是用来检索记录的主键.访问HBASE table中的行,只有三种方式: 1.通过单个RowKey访问 2.通过RowKey的range(正则) ...

  8. js中四舍五入保留两位效数,js中将Number转换成字符类型

    今天在写代码的时候遇到了点问题,特意记下,以免忘记!四舍五入方法: // num为传入的值,n为保留的小数位 function fomatFloat(num,n){ var f = parseFloa ...

  9. web自动化测试-selenium的三种等待

    一.等待的作用 1.在系统的功能运行过程中,所有的内容是需要一定的时间来实现展示, 2.时间耗费长短与网络速度.系统框架设定.接口的执行复杂度有关, 3.因此需要设置缓冲时间,若未设置缓冲时间,容易导 ...

  10. HTTP协议(待写)

    先来了解了解 TCP/IP TCP/IP(Transmission Control Protocol / Internet Protocol)是计算机通讯必须遵守的规则,是不同的通信协议的大集合,其里 ...