75 lines
2.6 KiB
C#
75 lines
2.6 KiB
C#
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 实例
|
||
}
|
||
}
|
||
}
|