初始化
This commit is contained in:
220
Common/CSRedisCacheHelper.cs
Normal file
220
Common/CSRedisCacheHelper.cs
Normal file
@@ -0,0 +1,220 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Configuration;
|
||||
using CSRedis;
|
||||
using LogCap.Common;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
||||
namespace Common
|
||||
{
|
||||
/// <summary>
|
||||
/// Redis缓存辅助类
|
||||
/// </summary>
|
||||
public class CSRedisCacheHelper
|
||||
{
|
||||
|
||||
public static CSRedisClient? redis = null;
|
||||
public static CSRedisClient? redis1 = null;
|
||||
public static CSRedisClient? redis2 = null;
|
||||
public static CSRedisClient? redis3 = null;
|
||||
public static CSRedisClient? redis4 = null;
|
||||
public static CSRedisClient? redis5 = null;
|
||||
public static int SessionExpireMinutes = 5;
|
||||
|
||||
public static IConfiguration Configuration { get; set; }
|
||||
|
||||
static CSRedisCacheHelper()
|
||||
{
|
||||
var redisHostStr = ReadConfig.Instance.get_redis_server_session;
|
||||
var get_redis_auth = ReadConfig.Instance.get_redis_auth;
|
||||
if (!string.IsNullOrEmpty(redisHostStr))
|
||||
{
|
||||
redis = new CSRedisClient(redisHostStr + string.Format(",password={0},defaultDatabase=0", get_redis_auth));
|
||||
redis1 = new CSRedisClient(redisHostStr + string.Format(",password={0},defaultDatabase=1", get_redis_auth));
|
||||
redis2 = new CSRedisClient(redisHostStr + string.Format(",password={0},defaultDatabase=2", get_redis_auth));
|
||||
redis3 = new CSRedisClient(redisHostStr + string.Format(",password={0},defaultDatabase=3", get_redis_auth));
|
||||
redis4 = new CSRedisClient(redisHostStr + string.Format(",password={0},defaultDatabase=4", get_redis_auth));
|
||||
redis5 = new CSRedisClient(redisHostStr + string.Format(",password={0},defaultDatabase=5", get_redis_auth));
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 添加缓存
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="value"></param>
|
||||
public static void Set<T>(string key, T value)
|
||||
{
|
||||
redis.Set(key, value, SessionExpireMinutes * 60);
|
||||
}
|
||||
|
||||
public static T Get<T>(string key)
|
||||
{
|
||||
return redis.Get<T>(key);
|
||||
}
|
||||
public static void Del(string[] key)
|
||||
{
|
||||
redis.Del(key.ToArray());
|
||||
}
|
||||
|
||||
public static T ForeverGet<T>(string key)
|
||||
{
|
||||
return redis1.Get<T>(key);
|
||||
}
|
||||
|
||||
public static void Forever<T>(string key, T value)
|
||||
{
|
||||
redis1.Set(key, value, 0);
|
||||
}
|
||||
|
||||
public static T Get_Partition<T>(string key, int SliceNo = 2)
|
||||
{
|
||||
CSRedisClient client = WhitchRedisSlice(SliceNo);
|
||||
return client.Get<T>(key);
|
||||
}
|
||||
public static void Set_Partition<T>(string key, T value, int SliceNo = 2, int ExpireMinutes = 0)
|
||||
{
|
||||
CSRedisClient client = WhitchRedisSlice(SliceNo);
|
||||
client.Set(key, value, ExpireMinutes * 60);
|
||||
}
|
||||
public static void Del_Partition(string[] key, int SliceNo = 2)
|
||||
{
|
||||
CSRedisClient client = WhitchRedisSlice(SliceNo);
|
||||
client.Del(key);
|
||||
}
|
||||
public static bool Contains_Partition(string key, int SliceNo = 2)
|
||||
{
|
||||
CSRedisClient client = WhitchRedisSlice(SliceNo);
|
||||
bool result = client.Exists(key);
|
||||
return result;
|
||||
}
|
||||
private static CSRedisClient WhitchRedisSlice(int SliceNo)
|
||||
{
|
||||
CSRedisClient client = null;
|
||||
if (SliceNo == 1)
|
||||
{
|
||||
client = redis1;
|
||||
}
|
||||
else if (SliceNo == 2)
|
||||
{
|
||||
client = redis2;
|
||||
}
|
||||
else
|
||||
{
|
||||
client = redis;
|
||||
}
|
||||
return client;
|
||||
}
|
||||
|
||||
public static long GetForever_ExpireMinutes<T>(string key)
|
||||
{
|
||||
return redis.Ttl(key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public static T Get<T>(string key, string mac)
|
||||
{
|
||||
T obj = redis.Get<T>(mac);
|
||||
if (obj == null)
|
||||
{
|
||||
return redis.Get<T>(key);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
/// <summary>
|
||||
/// 判断是否存在
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="mac"></param>
|
||||
/// <returns></returns>
|
||||
public static bool Contains(string key, string mac)
|
||||
{
|
||||
bool result = redis.Exists(mac);
|
||||
if (!result)
|
||||
{
|
||||
result = redis.Exists(key);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static bool Contains(string key)
|
||||
{
|
||||
bool result = redis.Exists(key);
|
||||
return result;
|
||||
}
|
||||
public static void Publish(string Topic, string Payload)
|
||||
{
|
||||
redis.PublishAsync(Topic,Payload);
|
||||
}
|
||||
/// <summary>
|
||||
/// 添加Hash缓存
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="value"></param>
|
||||
public static void HMSet(int SliceNo, string key, params object[] value)
|
||||
{
|
||||
CSRedisClient client = WhitchRedisSlice(SliceNo);
|
||||
client.HMSet(key, value);
|
||||
}
|
||||
|
||||
public static void HMSet(int SliceNo, int ExpireTime_M, string key, params object[] value)
|
||||
{
|
||||
CSRedisClient client = WhitchRedisSlice(SliceNo);
|
||||
client.HMSet(key, value);
|
||||
client.Expire(key, new TimeSpan(0, ExpireTime_M, 0));
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取Hash缓存
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public static T[] HMGet<T>(int SliceNo, string key, string KeyV)
|
||||
{
|
||||
CSRedisClient client = WhitchRedisSlice(SliceNo);
|
||||
return client.HMGet<T>(key, KeyV);
|
||||
}
|
||||
public static Dictionary<string, string> HMGetAll(int SliceNo, string key)
|
||||
{
|
||||
CSRedisClient client = WhitchRedisSlice(SliceNo);
|
||||
return client.HGetAll(key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除Hash缓存
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public static long HDelAll<T>(int SliceNo, string key)
|
||||
{
|
||||
CSRedisClient client = WhitchRedisSlice(SliceNo);
|
||||
return client.HDel(key);
|
||||
}
|
||||
public static long HDel(int SliceNo, string key, string key1)
|
||||
{
|
||||
CSRedisClient client = WhitchRedisSlice(SliceNo);
|
||||
return client.HDel(key, key1);
|
||||
}
|
||||
|
||||
public static void ListAdd(int SliceNo, string key, params object[] obj)
|
||||
{
|
||||
CSRedisClient client = WhitchRedisSlice(SliceNo);
|
||||
client.LPush(key, obj);
|
||||
}
|
||||
|
||||
|
||||
public static void GenericSerNo(string key)
|
||||
{
|
||||
redis1.IncrBy(key, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
105
Common/Cache/Cache.cs
Normal file
105
Common/Cache/Cache.cs
Normal file
@@ -0,0 +1,105 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using CommonEntity.CacheEntity;
|
||||
using FASTER.core;
|
||||
|
||||
namespace Common.Cache
|
||||
{
|
||||
public class Cache
|
||||
{
|
||||
private static System.Timers.Timer _checkpointTimer;
|
||||
public static FasterKVSettings<string, MyData_Cache> settings { get; set; }
|
||||
public static FasterKV<string, MyData_Cache> store { get; set; }
|
||||
public static ConcurrentBag<ClientSession<string, MyData_Cache, MyData_Cache, MyData_Cache, Empty, IFunctions<string, MyData_Cache, MyData_Cache, MyData_Cache, Empty>>> _sessions = new();
|
||||
|
||||
|
||||
static Cache()
|
||||
{
|
||||
settings = new FasterKVSettings<string, MyData_Cache>()
|
||||
{
|
||||
LogDevice = Devices.CreateLogDevice("c:/youtemp/log"), // 元数据日志
|
||||
ObjectLogDevice = Devices.CreateLogDevice("c:/youtemp/obj"), // 对象数据日志
|
||||
TryRecoverLatest = true,
|
||||
ValueSerializer = () => new MyValueSerializer<MyData_Cache>()
|
||||
};
|
||||
store = new FasterKV<string, MyData_Cache>(settings);
|
||||
var session1 = store.NewSession(new SimpleFunctions<string, MyData_Cache>());
|
||||
var session2 = store.NewSession(new SimpleFunctions<string, MyData_Cache>());
|
||||
var session3 = store.NewSession(new SimpleFunctions<string, MyData_Cache>());
|
||||
var session4 = store.NewSession(new SimpleFunctions<string, MyData_Cache>());
|
||||
var session5 = store.NewSession(new SimpleFunctions<string, MyData_Cache>());
|
||||
_sessions.Add(session1);
|
||||
_sessions.Add(session2);
|
||||
_sessions.Add(session3);
|
||||
_sessions.Add(session4);
|
||||
_sessions.Add(session5);
|
||||
_checkpointTimer = new System.Timers.Timer();
|
||||
_checkpointTimer.Interval = 60000; // 1分钟做一次检查点
|
||||
_checkpointTimer.Elapsed += _checkpointTimer_Elapsed;
|
||||
_checkpointTimer.Start();
|
||||
}
|
||||
|
||||
private async static void _checkpointTimer_Elapsed(object? sender, System.Timers.ElapsedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_sessions != null)
|
||||
{
|
||||
await store.TakeFullCheckpointAsync(CheckpointType.FoldOver);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task SetCache(string Key, MyData_Cache ValueData)
|
||||
{
|
||||
bool isexits = _sessions.TryTake(result: out var TakeSession);
|
||||
if (isexits)
|
||||
{
|
||||
TakeSession.Upsert(ref Key, ref ValueData);
|
||||
_sessions.Add(TakeSession);
|
||||
await TakeSession.CompletePendingAsync(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
var NewSession = store.NewSession(new SimpleFunctions<string, MyData_Cache>());
|
||||
var status = NewSession.Upsert(ref Key, ref ValueData);
|
||||
_sessions.Add(NewSession);
|
||||
}
|
||||
|
||||
//await store.TakeFullCheckpointAsync(CheckpointType.FoldOver);
|
||||
}
|
||||
public static async Task<MyData_Cache> GetCache(string Key)
|
||||
{
|
||||
MyData_Cache output = null;
|
||||
bool isexits = _sessions.TryTake(result: out var TakeSession);
|
||||
if (isexits)
|
||||
{
|
||||
_sessions.Add(TakeSession);
|
||||
|
||||
TakeSession.Refresh();
|
||||
var status = await TakeSession.ReadAsync(ref Key, ref output);
|
||||
MyData_Cache output1 = status.Output;
|
||||
output = output1;
|
||||
}
|
||||
else
|
||||
{
|
||||
var NewSession = store.NewSession(new SimpleFunctions<string, MyData_Cache>());
|
||||
_sessions.Add(NewSession);
|
||||
|
||||
|
||||
var status = await NewSession.ReadAsync(ref Key, ref output);
|
||||
MyData_Cache output1 = status.Output;
|
||||
output = output1;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
}
|
||||
}
|
||||
32
Common/Cache/MyValueSerializer.cs
Normal file
32
Common/Cache/MyValueSerializer.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection.PortableExecutable;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using FASTER.core;
|
||||
using System.Xml.Linq;
|
||||
using CommonEntity.CacheEntity;
|
||||
using MemoryPack;
|
||||
|
||||
namespace Common.Cache
|
||||
{
|
||||
|
||||
public class MyValueSerializer<T> : BinaryObjectSerializer<T>
|
||||
{
|
||||
public override void Serialize(ref T value)
|
||||
{
|
||||
//writer.Write(IPAddress.HostToNetworkOrder(Q.Length)); // 4字节长度头
|
||||
var Q = MemoryPackSerializer.Serialize(value);
|
||||
writer.Write(Q.Length); // 4字节长度头
|
||||
writer.Write(Q);
|
||||
}
|
||||
|
||||
public override void Deserialize(out T value)
|
||||
{
|
||||
int length = reader.ReadInt32(); // 读长度头
|
||||
byte[] buffer = reader.ReadBytes(length); // 读数据体
|
||||
value = MemoryPackSerializer.Deserialize<T>(buffer); // 反序列化
|
||||
}
|
||||
}
|
||||
}
|
||||
23
Common/CacheKey.cs
Normal file
23
Common/CacheKey.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace LogCap.Common
|
||||
{
|
||||
public class CacheKey
|
||||
{
|
||||
public static string RoomIP_Port_Prefix = "Log_IP_Port";
|
||||
|
||||
public static string Key = "monitor_host";
|
||||
|
||||
public static string MonitorLogPrefix = "AllLogKey_";
|
||||
|
||||
public static string MQTTValidatePrefix = "MQTTValidatePrefix_";
|
||||
|
||||
public static string DeviceInfo = "DeviceInfo";
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
24
Common/Common.csproj
Normal file
24
Common/Common.csproj
Normal file
@@ -0,0 +1,24 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CSRedisCore" Version="3.8.804" />
|
||||
<PackageReference Include="MessagePack" Version="3.1.4" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="8.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="9.0.5" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="9.0.5" />
|
||||
<PackageReference Include="Microsoft.Extensions.ObjectPool" Version="8.0.21" />
|
||||
<PackageReference Include="Microsoft.FASTER.Core" Version="2.6.5" />
|
||||
<PackageReference Include="RestSharp" Version="112.1.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\CommonEntity\CommonEntity.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
24
Common/DeviceConvert.cs
Normal file
24
Common/DeviceConvert.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Common
|
||||
{
|
||||
public class DeviceConvert
|
||||
{
|
||||
public static string Convert_To_Address(byte[] deviceAddress)
|
||||
{
|
||||
if (deviceAddress[0] == 0x00)//指令场景地址
|
||||
{
|
||||
return String.Format("{0}.{1}.{2}", deviceAddress[1], deviceAddress[2], deviceAddress[3]);
|
||||
}
|
||||
else
|
||||
{
|
||||
ushort type = BitConverter.ToUInt16(deviceAddress, 2);
|
||||
return String.Format("{0:000}{1:000}{2:000}", deviceAddress[0], deviceAddress[1], type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
33
Common/Grafana.cs
Normal file
33
Common/Grafana.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Common
|
||||
{
|
||||
public class Grafana
|
||||
{
|
||||
public static string WaiBuJianKongSourceFileName = "Para_copy.yaml";
|
||||
public static string WaiBuJianKongTargetFileName = "C:\\Program Files\\windows_exporter\\textfile_inputs\\Para.prom";
|
||||
public static string Data = "";
|
||||
|
||||
//static Grafana()
|
||||
//{
|
||||
// string getdata = File.ReadAllText(WaiBuJianKongSourceFileName, Encoding.UTF8);
|
||||
// Data = getdata;
|
||||
//}
|
||||
public static grafana_data data = new grafana_data();
|
||||
}
|
||||
public class grafana_data
|
||||
{
|
||||
public string? device_id { get; set; } = "0";
|
||||
public string? device_status { get; set; } = "0";
|
||||
public string? realtime_value { get; set; }= "0";
|
||||
public string? environment_value { get; set; }="0";
|
||||
public string? mcu_temperature { get; set; } = "0";
|
||||
public string? sensor_temperature { get; set; }= "0";
|
||||
public string? sensor_humidity { get; set; } = "0";
|
||||
public string? adc_raw_value { get; set; } = "0";
|
||||
}
|
||||
}
|
||||
45
Common/HttpSend.cs
Normal file
45
Common/HttpSend.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualBasic;
|
||||
using RestSharp;
|
||||
|
||||
namespace LogCap.Common
|
||||
{
|
||||
public class HttpSend
|
||||
{
|
||||
|
||||
public static readonly string debug_log_report_url = ReadConfig.Instance.get_debug_log_report_url;
|
||||
public static readonly string debug_log_report_mqtt_topic = ReadConfig.Instance.get_debug_log_report_mqtt_topic;
|
||||
|
||||
public static RestClient client1 = new RestClient(debug_log_report_url);
|
||||
public static async void SendLog(string MyCommandType, long hotel_code, int host_id, string roomnumber, string hostnumber, string WWW_IP, int WWW_Port, string lan_ip, int lan_port, string mac, string send_or_receive, string dataHex)
|
||||
{
|
||||
try
|
||||
{
|
||||
string ti = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
|
||||
|
||||
string mm = "";
|
||||
string str = Newtonsoft.Json.JsonConvert.SerializeObject(mm);
|
||||
//Console.WriteLine("发送MQTT的数据为:" + str);
|
||||
var request1 = new RestRequest("/", Method.Post);
|
||||
|
||||
//注意方法是POST
|
||||
//两个参数名字必须是 topic 和payload ,区分大小写的
|
||||
//Console.WriteLine("Topic: " + debug_log_report_mqtt_topic);
|
||||
request1.AddParameter("topic", debug_log_report_mqtt_topic);
|
||||
request1.AddParameter("payload", str);
|
||||
|
||||
await HttpSend.client1.ExecuteAsync(request1);
|
||||
Console.WriteLine("当前时间为:" + ti+" Data: "+dataHex);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("发送MQTT数据出错:" + ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
93
Common/Id_G.cs
Normal file
93
Common/Id_G.cs
Normal file
@@ -0,0 +1,93 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Common
|
||||
{
|
||||
public class IdWorker
|
||||
{
|
||||
//起始的时间戳
|
||||
private static long START_STMP = 1480166465631L;
|
||||
|
||||
//每一部分占用的位数
|
||||
private static int SEQUENCE_BIT = 12; //序列号占用的位数
|
||||
private static int MACHINE_BIT = 5; //机器标识占用的位数
|
||||
private static int DATACENTER_BIT = 5;//数据中心占用的位数
|
||||
|
||||
//每一部分的最大值
|
||||
private static long MAX_DATACENTER_NUM = -1L ^ (-1L << DATACENTER_BIT);
|
||||
private static long MAX_MACHINE_NUM = -1L ^ (-1L << MACHINE_BIT);
|
||||
private static long MAX_SEQUENCE = -1L ^ (-1L << SEQUENCE_BIT);
|
||||
|
||||
//每一部分向左的位移
|
||||
private static int MACHINE_LEFT = SEQUENCE_BIT;
|
||||
private static int DATACENTER_LEFT = SEQUENCE_BIT + MACHINE_BIT;
|
||||
private static int TIMESTMP_LEFT = DATACENTER_LEFT + DATACENTER_BIT;
|
||||
|
||||
private long datacenterId = 1; //数据中心
|
||||
private long machineId = 1; //机器标识
|
||||
private long sequence = 0L; //序列号
|
||||
private long lastStmp = -1L;//上一次时间戳
|
||||
|
||||
#region 单例:完全懒汉
|
||||
private static readonly Lazy<IdWorker> lazy = new Lazy<IdWorker>(() => new IdWorker());
|
||||
public static IdWorker Singleton { get { return lazy.Value; } }
|
||||
private IdWorker() { }
|
||||
#endregion
|
||||
|
||||
public IdWorker(long cid, long mid)
|
||||
{
|
||||
if (cid > MAX_DATACENTER_NUM || cid < 0) throw new Exception($"中心Id应在(0,{MAX_DATACENTER_NUM})之间");
|
||||
if (mid > MAX_MACHINE_NUM || mid < 0) throw new Exception($"机器Id应在(0,{MAX_MACHINE_NUM})之间");
|
||||
datacenterId = cid;
|
||||
machineId = mid;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 产生下一个ID
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public long nextId()
|
||||
{
|
||||
long currStmp = getNewstmp();
|
||||
if (currStmp < lastStmp) throw new Exception("时钟倒退,Id生成失败!");
|
||||
|
||||
if (currStmp == lastStmp)
|
||||
{
|
||||
//相同毫秒内,序列号自增
|
||||
sequence = (sequence + 1) & MAX_SEQUENCE;
|
||||
//同一毫秒的序列数已经达到最大
|
||||
if (sequence == 0L) currStmp = getNextMill();
|
||||
}
|
||||
else
|
||||
{
|
||||
//不同毫秒内,序列号置为0
|
||||
sequence = 0L;
|
||||
}
|
||||
|
||||
lastStmp = currStmp;
|
||||
|
||||
return (currStmp - START_STMP) << TIMESTMP_LEFT //时间戳部分
|
||||
| datacenterId << DATACENTER_LEFT //数据中心部分
|
||||
| machineId << MACHINE_LEFT //机器标识部分
|
||||
| sequence; //序列号部分
|
||||
}
|
||||
|
||||
private long getNextMill()
|
||||
{
|
||||
long mill = getNewstmp();
|
||||
while (mill <= lastStmp)
|
||||
{
|
||||
mill = getNewstmp();
|
||||
}
|
||||
return mill;
|
||||
}
|
||||
|
||||
private long getNewstmp()
|
||||
{
|
||||
return (long)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds;
|
||||
}
|
||||
}
|
||||
}
|
||||
44
Common/MyMessagePacker.cs
Normal file
44
Common/MyMessagePacker.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using MessagePack;
|
||||
|
||||
namespace CommonTools
|
||||
{
|
||||
public class MyMessagePacker
|
||||
{
|
||||
public static byte[] FastSerialize<T>(T t)
|
||||
{
|
||||
byte[] bytes = MessagePackSerializer.Serialize(t);
|
||||
return bytes;
|
||||
}
|
||||
public static T FastDeserialize<T>(byte[] bytes)
|
||||
{
|
||||
T mc2 = MessagePackSerializer.Deserialize<T>(bytes);
|
||||
return mc2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[MessagePackObject]
|
||||
public class MyClass
|
||||
{
|
||||
// Key attributes take a serialization index (or string name)
|
||||
// The values must be unique and versioning has to be considered as well.
|
||||
// Keys are described in later sections in more detail.
|
||||
[Key(0)]
|
||||
public int Age { get; set; }
|
||||
|
||||
[Key(1)]
|
||||
public string FirstName { get; set; }
|
||||
|
||||
[Key(2)]
|
||||
public string LastName { get; set; }
|
||||
|
||||
// All fields or properties that should not be serialized must be annotated with [IgnoreMember].
|
||||
[IgnoreMember]
|
||||
public string FullName { get { return FirstName + LastName; } }
|
||||
}
|
||||
}
|
||||
69
Common/ReadConfig.cs
Normal file
69
Common/ReadConfig.cs
Normal file
@@ -0,0 +1,69 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
||||
namespace LogCap.Common
|
||||
{
|
||||
public class ReadConfig
|
||||
{
|
||||
public static ReadConfig Instance = new ReadConfig();
|
||||
public IConfiguration? Configuration { get; set; }
|
||||
public string? MySQLConnectionString { get; set; }
|
||||
public string? get_monitor_filter { get; set; }
|
||||
public string? get_session_expire_minutes { get; set; }
|
||||
public string? get_redis_server_session { get; set; }
|
||||
public string? get_redis_auth { get; set; }
|
||||
public string? get_redis_max_read_pool { get; set; }
|
||||
public string? get_redis_max_write_pool { get; set; }
|
||||
public string? get_debug_log_report_url { get; set; }
|
||||
public string? get_debug_log_report_mqtt_topic { get; set; }
|
||||
|
||||
public string? monitor_log_expire_minutes { get; set; }
|
||||
|
||||
public string? monitor_server_ip { get; set; }
|
||||
public int monitor_server_port { get; set; }
|
||||
public string? CRICS_URL { get; set; }
|
||||
public string? MQTT_ServerIP { get; set; }
|
||||
public int? MQTT_ServerPort { get; set; }
|
||||
public string? MQTT_User { get; set; }
|
||||
public string? MQTT_PassWord { get; set; }
|
||||
|
||||
|
||||
public ReadConfig()
|
||||
{
|
||||
Configuration = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.json").Build();
|
||||
MySQLConnectionString = Configuration.GetConnectionString("SQLServerConnectionString");
|
||||
get_monitor_filter = Configuration.GetSection("monitor_filter").Value;
|
||||
|
||||
get_session_expire_minutes = Configuration.GetSection("session_expire_minutes").Value;
|
||||
get_redis_server_session = Configuration.GetSection("redis_server_session").Value;
|
||||
get_redis_auth = Configuration.GetSection("get_redis_auth").Value;
|
||||
get_redis_max_read_pool = Configuration.GetSection("redis_max_read_pool").Value;
|
||||
get_redis_max_write_pool = Configuration.GetSection("redis_max_write_pool").Value;
|
||||
|
||||
monitor_log_expire_minutes = Configuration.GetSection("monitor_log_expire_minutes").Value;
|
||||
|
||||
get_debug_log_report_url = Configuration.GetSection("debug_log_report_url").Value;
|
||||
get_debug_log_report_mqtt_topic = Configuration.GetSection("debug_log_report_mqtt_topic").Value;
|
||||
|
||||
monitor_server_ip = Configuration.GetSection("monitor_server_ip").Value;
|
||||
|
||||
int i = 3339;
|
||||
int.TryParse(Configuration.GetSection("monitor_server_port").Value, out i);
|
||||
monitor_server_port = i;
|
||||
|
||||
MQTT_ServerIP = Configuration.GetSection("MQTT_ServerIP").Value;
|
||||
|
||||
int p = 1883;
|
||||
int.TryParse(Configuration.GetSection("MQTT_ServerPort").Value, out p);
|
||||
MQTT_ServerPort = p;
|
||||
|
||||
CRICS_URL = Configuration.GetSection("CRICS_URL").Value;
|
||||
MQTT_User = Configuration.GetSection("MQTT_User").Value;
|
||||
MQTT_PassWord = Configuration.GetSection("MQTT_PWD").Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
21
Common/SnowIdGenerate/DisposableAction.cs
Normal file
21
Common/SnowIdGenerate/DisposableAction.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
|
||||
namespace Snowflake
|
||||
{
|
||||
public class DisposableAction : IDisposable
|
||||
{
|
||||
readonly Action _action;
|
||||
|
||||
public DisposableAction(Action action)
|
||||
{
|
||||
if (action == null)
|
||||
throw new ArgumentNullException("action");
|
||||
_action = action;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_action();
|
||||
}
|
||||
}
|
||||
}
|
||||
118
Common/SnowIdGenerate/IdWorker.cs
Normal file
118
Common/SnowIdGenerate/IdWorker.cs
Normal file
@@ -0,0 +1,118 @@
|
||||
/** Copyright 2010-2012 Twitter, Inc.*/
|
||||
|
||||
/**
|
||||
* An object that generates IDs.
|
||||
* This is broken into a separate class in case
|
||||
* we ever want to support multiple worker threads
|
||||
* per process
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace Snowflake
|
||||
{
|
||||
public class IdWorker
|
||||
{
|
||||
public const long Twepoch = 1288834974657L;
|
||||
|
||||
const int WorkerIdBits = 5;
|
||||
const int DatacenterIdBits = 5;
|
||||
const int SequenceBits = 12;
|
||||
const long MaxWorkerId = -1L ^ (-1L << WorkerIdBits);
|
||||
const long MaxDatacenterId = -1L ^ (-1L << DatacenterIdBits);
|
||||
|
||||
private const int WorkerIdShift = SequenceBits;
|
||||
private const int DatacenterIdShift = SequenceBits + WorkerIdBits;
|
||||
public const int TimestampLeftShift = SequenceBits + WorkerIdBits + DatacenterIdBits;
|
||||
private const long SequenceMask = -1L ^ (-1L << SequenceBits);
|
||||
|
||||
private long _sequence = 0L;
|
||||
private long _lastTimestamp = -1L;
|
||||
|
||||
|
||||
public IdWorker(long workerId, long datacenterId, long sequence = 0L)
|
||||
{
|
||||
WorkerId = workerId;
|
||||
DatacenterId = datacenterId;
|
||||
_sequence = sequence;
|
||||
|
||||
// sanity check for workerId
|
||||
if (workerId > MaxWorkerId || workerId < 0)
|
||||
{
|
||||
throw new ArgumentException( String.Format("worker Id can't be greater than {0} or less than 0", MaxWorkerId) );
|
||||
}
|
||||
|
||||
if (datacenterId > MaxDatacenterId || datacenterId < 0)
|
||||
{
|
||||
throw new ArgumentException( String.Format("datacenter Id can't be greater than {0} or less than 0", MaxDatacenterId));
|
||||
}
|
||||
|
||||
//log.info(
|
||||
// String.Format("worker starting. timestamp left shift {0}, datacenter id bits {1}, worker id bits {2}, sequence bits {3}, workerid {4}",
|
||||
// TimestampLeftShift, DatacenterIdBits, WorkerIdBits, SequenceBits, workerId)
|
||||
// );
|
||||
}
|
||||
|
||||
public long WorkerId {get; protected set;}
|
||||
public long DatacenterId {get; protected set;}
|
||||
|
||||
public long Sequence
|
||||
{
|
||||
get { return _sequence; }
|
||||
internal set { _sequence = value; }
|
||||
}
|
||||
|
||||
// def get_timestamp() = System.currentTimeMillis
|
||||
|
||||
readonly object _lock = new Object();
|
||||
|
||||
public virtual long NextId()
|
||||
{
|
||||
lock(_lock)
|
||||
{
|
||||
var timestamp = TimeGen();
|
||||
|
||||
if (timestamp < _lastTimestamp)
|
||||
{
|
||||
//exceptionCounter.incr(1);
|
||||
//log.Error("clock is moving backwards. Rejecting requests until %d.", _lastTimestamp);
|
||||
throw new InvalidSystemClock(String.Format(
|
||||
"Clock moved backwards. Refusing to generate id for {0} milliseconds", _lastTimestamp - timestamp));
|
||||
}
|
||||
|
||||
if (_lastTimestamp == timestamp)
|
||||
{
|
||||
_sequence = (_sequence + 1) & SequenceMask;
|
||||
if (_sequence == 0)
|
||||
{
|
||||
timestamp = TilNextMillis(_lastTimestamp);
|
||||
}
|
||||
} else {
|
||||
_sequence = 0;
|
||||
}
|
||||
|
||||
_lastTimestamp = timestamp;
|
||||
var id = ((timestamp - Twepoch) << TimestampLeftShift) |
|
||||
(DatacenterId << DatacenterIdShift) |
|
||||
(WorkerId << WorkerIdShift) | _sequence;
|
||||
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual long TilNextMillis(long lastTimestamp)
|
||||
{
|
||||
var timestamp = TimeGen();
|
||||
while (timestamp <= lastTimestamp)
|
||||
{
|
||||
timestamp = TimeGen();
|
||||
}
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
protected virtual long TimeGen()
|
||||
{
|
||||
return System.CurrentTimeMillis();
|
||||
}
|
||||
}
|
||||
}
|
||||
9
Common/SnowIdGenerate/InvalidSystemClock.cs
Normal file
9
Common/SnowIdGenerate/InvalidSystemClock.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using System;
|
||||
|
||||
namespace Snowflake
|
||||
{
|
||||
public class InvalidSystemClock : Exception
|
||||
{
|
||||
public InvalidSystemClock(string message) : base(message) { }
|
||||
}
|
||||
}
|
||||
40
Common/SnowIdGenerate/TimeExtensions.cs
Normal file
40
Common/SnowIdGenerate/TimeExtensions.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using System;
|
||||
|
||||
namespace Snowflake
|
||||
{
|
||||
public static class System
|
||||
{
|
||||
public static Func<long> currentTimeFunc = InternalCurrentTimeMillis;
|
||||
|
||||
public static long CurrentTimeMillis()
|
||||
{
|
||||
return currentTimeFunc();
|
||||
}
|
||||
|
||||
public static IDisposable StubCurrentTime(Func<long> func)
|
||||
{
|
||||
currentTimeFunc = func;
|
||||
return new DisposableAction(() =>
|
||||
{
|
||||
currentTimeFunc = InternalCurrentTimeMillis;
|
||||
});
|
||||
}
|
||||
|
||||
public static IDisposable StubCurrentTime(long millis)
|
||||
{
|
||||
currentTimeFunc = () => millis;
|
||||
return new DisposableAction(() =>
|
||||
{
|
||||
currentTimeFunc = InternalCurrentTimeMillis;
|
||||
});
|
||||
}
|
||||
|
||||
private static readonly DateTime Jan1st1970 = new DateTime
|
||||
(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
||||
|
||||
private static long InternalCurrentTimeMillis()
|
||||
{
|
||||
return (long)(DateTime.UtcNow - Jan1st1970).TotalMilliseconds;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user