コード例 #1
0
        /// <summary>
        /// 发送消息到队列,使用List实现,有重复
        /// (过期时间为整个Key内的所有消息过期,从第一个消息的Key开始)
        /// </summary>
        /// <param name="queueKeyPrefix">队列Key前缀</param>
        /// <param name="msg">发送的消息</param>
        /// <param name="keyExpiryTimeType">Key过期时间类型,默认为小时</param>
        /// <param name="expiryTimes">key过期时间类型的倍数,如过期时间是按小时,则表示多少小时后过期</param>
        /// <returns>返回是否发送成功</returns>
        private async Task <bool> SendQueueWithKeyExpiryAsync(string queueKeyPrefix,
                                                              string msg,
                                                              KeyExpiryTimeType keyExpiryTimeType = KeyExpiryTimeType.Hours,
                                                              int expiryTimes         = 2,
                                                              CancellationToken token = default)
        {
            if (string.IsNullOrEmpty(msg))
            {
                throw new ArgumentNullException($"please set param {nameof(msg)}!");
            }
            if (expiryTimes <= 1)
            {
                throw new ArgumentNullException($"param {nameof(expiryTimes)} must be greater than 1 !");
            }
            TimeSpan expiry = GetKeyExpiryTime(keyExpiryTimeType, expiryTimes);

            //lock (lockObj)
            using (await ListWriteSyncSemaphore.LockAsync(token))
            {
                RedisKey queueKey  = GetQueueKey(keyExpiryTimeType, RedisDataType.List, queueKeyPrefix);
                var      keyExists = await redis.GetDatabase().KeyExistsAsync(queueKey);

                RedisValue queueItems = msg;
                //var aaa = redis.GetDatabase().List(queueKey, queueItems, When.NotExists);
                var when       = When.Always;//List 不能用NotExists
                var pushResult = await redis.GetDatabase().ListLeftPushAsync(queueKey, queueItems, when);

                if (!keyExists && pushResult > 0)
                {
                    await redis.GetDatabase().KeyExpireAsync(queueKey, expiry);
                }
                return(pushResult > 0);
            }
        }
コード例 #2
0
        /// <summary>
        /// 发送消息到排序队列,使用ZSET,同一Key内无重复
        /// 排序按照时间戳升序
        /// (过期时间为整个Key内的所有消息过期,从第一个消息的Key开始)
        /// </summary>
        /// <param name="queueKeyPrefix">队列Key前缀</param>
        /// <param name="msg">发送的消息</param>
        /// <param name="expiryHours">过期小时</param>
        /// <returns>返回是否发送成功</returns>
        private async Task <bool> SendSortQueueWithKeyExpiryAsync(
            string queueKeyPrefix,
            string msg,
            KeyExpiryTimeType keyExpiryTimeType = KeyExpiryTimeType.Hours,
            int expiryTimes         = 2,
            CancellationToken token = default)
        {
            if (string.IsNullOrEmpty(msg))
            {
                throw new ArgumentNullException($"please set param {nameof(msg)}!");
            }
            if (expiryTimes <= 1)
            {
                throw new ArgumentNullException($"param {nameof(expiryTimes)} must be greater than 1 !");
            }
            TimeSpan expiry = GetKeyExpiryTime(keyExpiryTimeType, expiryTimes);

            //lock (lockObj)
            using (await ZSetWriteSyncSemaphore.LockAsync(token))
            {
                RedisKey   queueKey   = GetQueueKey(keyExpiryTimeType, RedisDataType.ZSet, queueKeyPrefix);
                RedisValue queueItems = msg;
                var        score      = DateTime.Now.Ticks;
                var        when       = When.NotExists;
                var        keyExists  = await redis.GetDatabase().KeyExistsAsync(queueKey);

                var addResult = await redis.GetDatabase().SortedSetAddAsync(queueKey, queueItems, score, when);

                if (!keyExists && addResult)
                {
                    await redis.GetDatabase().KeyExpireAsync(queueKey, expiry);
                }
                return(addResult);
            }
        }
コード例 #3
0
        /// <summary>
        /// 发送消息到排序队列,使用ZSET,同一Key内无重复
        /// 排序按照时间戳升序
        /// (过期时间为整个Key内的所有消息过期,从第一个消息的Key开始)
        /// </summary>
        /// <param name="queueKeyPrefix">队列Key前缀</param>
        /// <param name="msg">发送的消息</param>
        /// <param name="keyExpiryTimeType">Key过期时间类型,默认为小时</param>
        /// <param name="expiryTimes">key过期时间类型的倍数,如过期时间是按小时,则表示多少小时后过期</param>
        /// <returns>返回是否发送成功</returns>
        private bool SendSortQueueWithKeyExpiry(string queueKeyPrefix,
                                                string msg,
                                                KeyExpiryTimeType keyExpiryTimeType = KeyExpiryTimeType.Hours,
                                                int expiryTimes = 2)
        {
            if (string.IsNullOrEmpty(msg))
            {
                throw new ArgumentNullException($"please set param {nameof(msg)}!");
            }
            if (expiryTimes <= 1)
            {
                throw new ArgumentNullException($"param {nameof(expiryTimes)} must be greater than 1 !");
            }
            TimeSpan expiry = GetKeyExpiryTime(keyExpiryTimeType, expiryTimes);

            lock (ZSetWriteObj)
            {
                RedisKey   queueKey   = GetQueueKey(keyExpiryTimeType, RedisDataType.ZSet, queueKeyPrefix);
                var        keyExists  = redis.GetDatabase().KeyExists(queueKey);
                RedisValue queueItems = msg;
                var        score      = DateTime.Now.Ticks;
                var        when       = When.NotExists;
                var        addResult  = redis.GetDatabase().SortedSetAdd(queueKey, queueItems, score, when);
                if (!keyExists && addResult)
                {
                    redis.GetDatabase().KeyExpire(queueKey, expiry);
                }
                return(addResult);
            }
        }
コード例 #4
0
        private string GetQueueKeyPattern(KeyExpiryTimeType keyExpiryTimeType, RedisDataType redisDataType, string queueKeyPrefix)
        {
            var queueKeyPattern = queueKeyPrefix + (redisDataType == RedisDataType.List ? listQueueKeyPrefix : zsetQueueKeyPrefix);

            var timesNodeStr         = "Hours";
            var timesFormatKeySuffix = "";

            if (keyExpiryTimeType == KeyExpiryTimeType.Hours)
            {
                timesNodeStr         = "Hours";
                timesFormatKeySuffix = hoursFormatKeySuffix.Replace("yyyy", "*").
                                       Replace("MM", "*").
                                       Replace("dd", "*").
                                       Replace("HH", "*")
                ;
            }
            else if (keyExpiryTimeType == KeyExpiryTimeType.Minutes)
            {
                timesNodeStr         = "Minutes";
                timesFormatKeySuffix = minutesFormatKeySuffix.Replace("yyyy", "*").
                                       Replace("MM", "*").
                                       Replace("dd", "*").
                                       Replace("HH", "*").Replace("mm", "*");
            }
            queueKeyPattern += timesNodeStr + ":" + timesFormatKeySuffix;

            return(queueKeyPattern);
        }
コード例 #5
0
        /// <summary>
        /// 接收队列消息
        /// (过期时间为整个Key内的所有消息过期,从第一个消息的Key开始)
        /// </summary>
        /// <param name="queueKeyPrefix">队列Key前缀</param>
        /// <param name="count">获取消息数量</param>
        /// <returns>返回消息列表</returns>
        private List <string> GetMessageByKeyExpiry(string queueKeyPrefix,
                                                    int count = 1,
                                                    KeyExpiryTimeType keyExpiryTimeType = KeyExpiryTimeType.Hours
                                                    )
        {
            if (count <= 0)
            {
                throw new ArgumentNullException($"param {nameof(count)} must be greater than 0 !");
            }
            var msgList         = new List <string>();
            var queueKeyPattern = GetQueueKeyPattern(keyExpiryTimeType, RedisDataType.List, queueKeyPrefix);
            var keyList         = GetkeysByPrefix(queueKeyPattern);

            foreach (var item in keyList)
            {
                RedisKey queueKey  = item;
                var      keyExists = redis.GetDatabase().KeyExists(queueKey);
                if (!keyExists)
                {
                    continue;
                }
                while (msgList.Count < count && redis.GetDatabase().ListLength(queueKey) > 0)
                {
                    var msgV = redis.GetDatabase().ListRightPop(queueKey);
                    msgList.Add(msgV);
                    if (msgList.Count == count)
                    {
                        return(msgList);
                    }
                }
            }
            return(msgList);
        }
コード例 #6
0
        /// <summary>
        /// 发送消息到队列,使用List实现,有重复
        /// (过期时间为整个Key内的所有消息过期,从第一个消息的Key开始)
        /// </summary>
        /// <param name="queueKeyPrefix">队列Key前缀</param>
        /// <param name="msg">发送的消息</param>
        /// <param name="keyExpiryTimeType">Key过期时间类型,默认为小时</param>
        /// <param name="expiryTimes">key过期时间类型的倍数,如过期时间是按小时,则表示多少小时后过期</param>
        /// <returns>返回是否发送成功</returns>
        private bool SendQueueWithKeyExpiry(string queueKeyPrefix,
                                            string msg,
                                            KeyExpiryTimeType keyExpiryTimeType = KeyExpiryTimeType.Hours,
                                            int expiryTimes = 2)
        {
            if (string.IsNullOrEmpty(msg))
            {
                throw new ArgumentNullException($"please set param {nameof(msg)}!");
            }
            if (expiryTimes <= 1)
            {
                throw new ArgumentNullException($"param {nameof(expiryTimes)} must be greater than 1 !");
            }
            TimeSpan expiry = GetKeyExpiryTime(keyExpiryTimeType, expiryTimes);

            lock (ListWriteObj)
            {
                RedisKey   queueKey   = GetQueueKey(keyExpiryTimeType, RedisDataType.List, queueKeyPrefix);
                var        keyExists  = redis.GetDatabase().KeyExists(queueKey);
                RedisValue queueItems = msg;
                //var aaa = redis.GetDatabase().List(queueKey, queueItems, When.NotExists);
                var when       = When.Always;//List 不能用NotExists
                var pushResult = redis.GetDatabase().ListLeftPush(queueKey, queueItems, when);
                if (!keyExists && pushResult > 0)
                {
                    redis.GetDatabase().KeyExpire(queueKey, expiry);
                }
                return(pushResult > 0);
            }
        }
コード例 #7
0
        private TimeSpan GetKeyExpiryTime(KeyExpiryTimeType keyExpiryTimeType, int expiryTimes)
        {
            TimeSpan expiry = TimeSpan.FromHours(expiryTimes);

            if (keyExpiryTimeType == KeyExpiryTimeType.Hours)
            {
                expiry = TimeSpan.FromHours(expiryTimes);
            }
            else if (keyExpiryTimeType == KeyExpiryTimeType.Minutes)
            {
                expiry = TimeSpan.FromMinutes(expiryTimes);
            }
            return(expiry);
        }
コード例 #8
0
        /// <summary>
        /// 接收队列消息
        /// (过期时间为整个Key内的所有消息过期,从第一个消息的Key开始)
        /// </summary>
        /// <param name="queueKeyPrefix">队列Key前缀</param>
        /// <param name="count">获取消息数量</param>
        /// <returns>返回消息列表</returns>
        private async Task <List <string> > GetMessageByKeyExpiryAsync(string queueKeyPrefix,
                                                                       int count = 1,
                                                                       KeyExpiryTimeType keyExpiryTimeType = KeyExpiryTimeType.Hours)
        {
            if (count <= 0)
            {
                throw new ArgumentNullException($"param {nameof(count)} must be greater than 0 !");
            }
            var msgList         = new List <string>();
            var queueKeyPattern = GetQueueKeyPattern(keyExpiryTimeType, RedisDataType.List, queueKeyPrefix);

#if NETCOREAPP3_0 || NETCOREAPP3_1
            var keyList = await GetkeysByPrefixAsync(queueKeyPattern);
#else
            var keyList = GetkeysByPrefix(queueKeyPattern);
#endif
            foreach (var item in keyList)
            {
                RedisKey queueKey  = item;
                var      keyExists = await redis.GetDatabase().KeyExistsAsync(queueKey);

                if (!keyExists)
                {
                    continue;
                }
                while (msgList.Count < count && (await redis.GetDatabase().ListLengthAsync(queueKey)) > 0)
                {
                    var msgV = await redis.GetDatabase().ListRightPopAsync(queueKey);

                    /*
                     * var startIndex = 0;
                     * var endIndex = count - 1;
                     * var msgVList =await redis.GetDatabase().ListRangeAsync(queueKey,startIndex,endIndex);
                     */
                    msgList.Add(msgV);
                    if (msgList.Count == count)
                    {
                        return(msgList);
                    }
                }
            }
            return(msgList);
        }
コード例 #9
0
        private RedisKey GetQueueKey(KeyExpiryTimeType keyExpiryTimeType, RedisDataType redisDataType, string queueKeyPrefix)
        {
            var currentTime  = DateTime.Now.ToString(hoursFormatKeySuffix);
            var timesNodeStr = "Hours";

            if (keyExpiryTimeType == KeyExpiryTimeType.Hours)
            {
                currentTime  = DateTime.Now.ToString(hoursFormatKeySuffix);
                timesNodeStr = "Hours";
            }
            else if (keyExpiryTimeType == KeyExpiryTimeType.Minutes)
            {
                currentTime  = DateTime.Now.ToString(minutesFormatKeySuffix);
                timesNodeStr = "Minutes";
            }

            RedisKey queueKey = queueKeyPrefix + (redisDataType == RedisDataType.List? listQueueKeyPrefix:zsetQueueKeyPrefix) + timesNodeStr + ":" + currentTime;

            return(queueKey);
        }
コード例 #10
0
        /// <summary>
        /// 接收排序队列消息
        /// (过期时间为整个Key内的所有消息过期,从第一个消息的Key开始)
        /// </summary>
        /// <param name="queueKeyPrefix">队列Key前缀</param>
        /// <param name="count">获取消息数量</param>
        /// <param name="keyExpiryTimeType">Key过期时间类型,默认为小时</param>
        /// <returns>返回消息列表</returns>
        private async Task <List <string> > GetSortMessageByKeyExpiryAsync(
            string queueKeyPrefix,
            int count = 1,
            KeyExpiryTimeType keyExpiryTimeType = KeyExpiryTimeType.Hours,
            CancellationToken token             = default)
        {
            bool getBySingle = false;
            var  msgList     = new List <string>();

            if (count <= 0)
            {
                throw new ArgumentNullException($"param {nameof(count)} must be greater than 0 !");
            }
            var queueKeyPattern = GetQueueKeyPattern(keyExpiryTimeType, RedisDataType.ZSet, queueKeyPrefix);

#if NETCOREAPP3_0 || NETCOREAPP3_1
            var keyList = await GetkeysByPrefixAsync(queueKeyPattern);
#else
            var keyList = GetkeysByPrefix(queueKeyPattern);
#endif
            foreach (var item in keyList)
            {
                RedisKey queueKey  = item;
                var      keyExists = redis.GetDatabase().KeyExists(queueKey);
                if (!keyExists)
                {
                    continue;
                }

                while (msgList.Count < count && (await redis.GetDatabase().SortedSetLengthAsync(queueKey)) > 0)
                {
                    //ZPOPMIN命令需要Redis 5及以上版本SortedSetPop方法
                    //redis.GetDatabase().SortedSetScan(queueKey,, Order.Ascending);
                    if (getBySingle)
                    {
                        if (RedisServerVersion < new Version("5.0.0"))
                        {
                            var startIndex = 0;
                            var endIndex   = 0;
                            var vList      = await redis.GetDatabase().SortedSetRangeByRankAsync(queueKey, startIndex, endIndex, Order.Ascending);

                            if (vList == null || vList.Count() == 0)
                            {
                                break;
                            }
                            var msgV = vList.FirstOrDefault();
                            msgList.Add(msgV);
                            await redis.GetDatabase().SortedSetRemoveAsync(queueKey, msgV);
                        }
                        else
                        {
                            var sortedSetEntry = await redis.GetDatabase().SortedSetPopAsync(queueKey, Order.Ascending);

                            if (!sortedSetEntry.HasValue)
                            {
                                break;
                            }
                            var msgV = sortedSetEntry.Value.Element;
                            msgList.Add(msgV);
                        }
                        if (msgList.Count == count)
                        {
                            return(msgList);
                        }
                    }
                    else
                    {
                        var getCount = count - msgList.Count;
                        if (getCount == 0)
                        {
                            return(msgList);
                        }

                        if (RedisServerVersion < new Version("5.0.0"))
                        {
                            using (await ZSetReadSyncSemaphore.LockAsync(token))
                            {
                                var startIndex = 0;
                                var endIndex   = getCount - 1;
                                var vList      = await redis.GetDatabase().SortedSetRangeByRankAsync(queueKey, startIndex, endIndex, Order.Ascending);

                                if (vList == null || vList.Count() == 0)
                                {
                                    break;
                                }
                                await redis.GetDatabase().SortedSetRemoveAsync(queueKey, vList);

                                foreach (var msgV in vList)
                                {
                                    msgList.Add(msgV);
                                    //await redis.GetDatabase().SortedSetRemoveAsync(queueKey, msgV);
                                }
                            }
                        }
                        else
                        {
                            var sortedSetEntryList = await redis.GetDatabase().SortedSetPopAsync(queueKey, getCount, Order.Ascending);

                            if (sortedSetEntryList == null || sortedSetEntryList.Length == 0)
                            {
                                break;
                            }
                            foreach (var sortedSetEntry in sortedSetEntryList)
                            {
                                var msgV = sortedSetEntry.Element;
                                msgList.Add(msgV);
                            }
                        }
                        if (msgList.Count == count)
                        {
                            return(msgList);
                        }
                    }
                }
            }
            return(msgList);
        }
コード例 #11
0
        /// <summary>
        /// 接收排序队列消息
        /// (过期时间为整个Key内的所有消息过期,从第一个消息的Key开始)
        /// </summary>
        /// <param name="queueKeyPrefix">队列Key前缀</param>
        /// <param name="count">获取消息数量</param>
        /// <param name="keyExpiryTimeType">Key过期时间类型,默认为小时</param>
        /// <returns>返回消息列表</returns>
        private List <string> GetSortMessageByKeyExpiry(
            string queueKeyPrefix,
            int count = 1,
            KeyExpiryTimeType keyExpiryTimeType = KeyExpiryTimeType.Hours
            )
        {
            bool getBySingle = false;
            var  msgList     = new List <string>();

            if (count <= 0)
            {
                throw new ArgumentNullException($"param {nameof(count)} must be greater than 0 !");
            }
            var queueKeyPattern = GetQueueKeyPattern(keyExpiryTimeType, RedisDataType.ZSet, queueKeyPrefix);
            var keyList         = GetkeysByPrefix(queueKeyPattern);

            foreach (var item in keyList)
            {
                RedisKey queueKey  = item;
                var      keyExists = redis.GetDatabase().KeyExists(queueKey);
                if (!keyExists)
                {
                    continue;
                }

                while (msgList.Count < count && redis.GetDatabase().SortedSetLength(queueKey) > 0)
                {
                    //ZPOPMIN命令需要Redis 5及以上版本SortedSetPop方法
                    //redis.GetDatabase().SortedSetScan(queueKey,, Order.Ascending);
                    if (getBySingle)
                    {
                        if (RedisServerVersion < new Version("5.0.0"))
                        {
                            var startIndex = 0;
                            var endIndex   = 0;
                            var vList      = redis.GetDatabase().SortedSetRangeByRank(queueKey, startIndex, endIndex, Order.Ascending);
                            if (vList == null || vList.Count() == 0)
                            {
                                break;
                            }
                            var msgV = vList.FirstOrDefault();
                            msgList.Add(msgV);
                            redis.GetDatabase().SortedSetRemove(queueKey, msgV);
                        }
                        else
                        {
                            var sortedSetEntry = redis.GetDatabase().SortedSetPop(queueKey, Order.Ascending);
                            if (!sortedSetEntry.HasValue)
                            {
                                break;
                            }
                            var msgV = sortedSetEntry.Value.Element;
                            msgList.Add(msgV);
                        }
                        if (msgList.Count == count)
                        {
                            return(msgList);
                        }
                    }
                    else
                    {
                        var getCount = count - msgList.Count;
                        if (getCount == 0)
                        {
                            return(msgList);
                        }

                        if (RedisServerVersion < new Version("5.0.0"))
                        {
                            lock (ZSetReadObj)
                            {
                                var startIndex = 0;
                                var endIndex   = getCount - 1;
                                var vList      = redis.GetDatabase().SortedSetRangeByRank(queueKey, startIndex, endIndex, Order.Ascending);
                                if (vList == null || vList.Count() == 0)
                                {
                                    break;
                                }
                                redis.GetDatabase().SortedSetRemove(queueKey, vList);
                                foreach (var msgV in vList)
                                {
                                    msgList.Add(msgV);
                                    //redis.GetDatabase().SortedSetRemove(queueKey, msgV);
                                }
                            }
                        }
                        else
                        {
                            var sortedSetEntryList = redis.GetDatabase().SortedSetPop(queueKey, getCount, Order.Ascending);
                            if (sortedSetEntryList == null || sortedSetEntryList.Length == 0)
                            {
                                break;
                            }
                            foreach (var sortedSetEntry in sortedSetEntryList)
                            {
                                var msgV = sortedSetEntry.Element;
                                msgList.Add(msgV);
                            }
                        }
                        if (msgList.Count == count)
                        {
                            return(msgList);
                        }
                    }
                }
            }
            return(msgList);
        }