CSharp.Template/YuanXuan.IM.Api/Helper/WorkerIdAutoRegisterHelper.cs

75 lines
2.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using Yitter.IdGenerator;
using YuanXuan.IM.Infrastructure.Redis;
namespace YuanXuan.IM.Api.Helper
{
/// <summary>
/// IdWorker自动注册帮助类 需要先注册Redis
/// </summary>
public class WorkerIdAutoRegisterHelper
{
private static System.Timers.Timer _timer;
public static IdGeneratorOptions GetIdGeneratorOptions()
{
byte workerIdBitLength = 6;
var maxWorkId = Math.Pow(2, workerIdBitLength) - 1;
var workIdKey = "idgen:workid";
var workId = GetNextWorkId();
while (!RedisHelper.Instance.SetNx($"{workIdKey}:{workId}", 1))
{
// workId 已被占用获取下一个workId
workId = GetNextWorkId();
};
// 设置5分钟过期
RedisHelper.Instance.Expire($"{workIdKey}:{workId}", 60 * 5);
// 设置定时器每4分钟更新一次过期时间
SetTimer(4, (s, e) =>
{
RedisHelper.Instance.Expire($"{workIdKey}:{workId}", 60 * 5);
});
// WorkerIdBitLength + SeqBitLength 不超过 22
return new IdGeneratorOptions
{
WorkerIdBitLength = workerIdBitLength,
SeqBitLength = 6, // 数值越高性能越好但是Id也越长
WorkerId = (ushort)workId
};
long GetNextWorkId()
{
var workId = RedisHelper.Instance.IncrBy(workIdKey,1);
if (workId > maxWorkId)
{
// 大于了最大可用WorkId,重置workId并获取
RedisHelper.Instance.Set(workIdKey, 0);
workId = RedisHelper.Instance.IncrBy(workIdKey, 1);
}
Console.WriteLine($"================================================分配到的workId:{workId}===============================================================================");
return workId;
}
}
private static void SetTimer(int mins, ElapsedEventHandler eh)
{
// 创建一个 Timer 实例,并设置其相关属性
_timer = new System.Timers.Timer(TimeSpan.FromMinutes(mins).TotalMilliseconds); // 4 分钟
_timer.Elapsed += eh;
_timer.AutoReset = true; // 设置 Timer 实例能否多次触发
_timer.Enabled = true; // 启动 Timer 实例
}
}
}