feat(新增): 添加Quartz简单案例
This commit is contained in:
parent
e48c71c1e1
commit
aad873a49a
|
@ -2,19 +2,7 @@
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="GitCommitMessageStorage">
|
<component name="GitCommitMessageStorage">
|
||||||
<option name="messageStorage">
|
<option name="messageStorage">
|
||||||
<MessageStorage>
|
<MessageStorage />
|
||||||
<option name="commitTemplate">
|
|
||||||
<CommitTemplate>
|
|
||||||
<option name="body" value="" />
|
|
||||||
<option name="changes" value="" />
|
|
||||||
<option name="closes" value="" />
|
|
||||||
<option name="scope" value="" />
|
|
||||||
<option name="skipCi" value="" />
|
|
||||||
<option name="subject" value="" />
|
|
||||||
<option name="type" value="feat" />
|
|
||||||
</CommitTemplate>
|
|
||||||
</option>
|
|
||||||
</MessageStorage>
|
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
|
@ -19,6 +19,7 @@
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
<PackageReference Include="Minio" Version="6.0.3"/>
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3"/>
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3"/>
|
||||||
<PackageReference Include="StackExchange.Redis" Version="2.8.0"/>
|
<PackageReference Include="StackExchange.Redis" Version="2.8.0"/>
|
||||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="7.6.0"/>
|
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="7.6.0"/>
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
using Bunny.Common.Utils;
|
||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Minio;
|
||||||
|
|
||||||
|
namespace Bunny.Common.Connect;
|
||||||
|
|
||||||
|
public static class MinioContext
|
||||||
|
{
|
||||||
|
public static IMinioClient? MinioClient;
|
||||||
|
public static readonly string BucketName = AppSettings.GetConfig("Minio:BucketName");
|
||||||
|
|
||||||
|
public static void AddMinioContext(this WebApplicationBuilder builder)
|
||||||
|
{
|
||||||
|
var endpoint = AppSettings.GetConfig("Minio:Url");
|
||||||
|
var accessKey = AppSettings.GetConfig("Minio:AccessKey");
|
||||||
|
var secretKey = AppSettings.GetConfig("Minio:SecretKey");
|
||||||
|
|
||||||
|
MinioClient = new MinioClient().WithEndpoint(endpoint).WithCredentials(accessKey, secretKey)
|
||||||
|
// .WithSSL() // 使用HTTPS
|
||||||
|
.Build();
|
||||||
|
Task.Run(ShowAllBucket);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task ShowAllBucket()
|
||||||
|
{
|
||||||
|
var listBucketsAsync = await MinioUtil.ListBucketsAsync();
|
||||||
|
foreach (var bucket in listBucketsAsync.Buckets) Console.WriteLine($"Minio存在的桶:{bucket.Name}");
|
||||||
|
|
||||||
|
Console.WriteLine("Minio 连接成功...");
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,13 +1,14 @@
|
||||||
using StackExchange.Redis;
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using StackExchange.Redis;
|
||||||
|
|
||||||
namespace Bunny.Common.Connect;
|
namespace Bunny.Common.Connect;
|
||||||
|
|
||||||
public class RedisContext
|
public static class RedisContext
|
||||||
{
|
{
|
||||||
public static IDatabase RedisDatabase;
|
public static IDatabase RedisDatabase;
|
||||||
private static readonly EndPointCollection EndPointCollection = new();
|
private static readonly EndPointCollection EndPointCollection = new();
|
||||||
|
|
||||||
public static void Initial()
|
public static void AddRedisContext(this WebApplicationBuilder builder)
|
||||||
{
|
{
|
||||||
// 获取端口等配置信息
|
// 获取端口等配置信息
|
||||||
var host = AppSettings.GetConfig("Redis:Host");
|
var host = AppSettings.GetConfig("Redis:Host");
|
||||||
|
|
|
@ -0,0 +1,205 @@
|
||||||
|
using Bunny.Common.Connect;
|
||||||
|
using Bunny.Common.Exception;
|
||||||
|
using Bunny.Dao.Entity.Constant;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.IdentityModel.Tokens;
|
||||||
|
using Minio.DataModel;
|
||||||
|
using Minio.DataModel.Args;
|
||||||
|
using Minio.DataModel.Result;
|
||||||
|
using Minio.Exceptions;
|
||||||
|
|
||||||
|
namespace Bunny.Common.Utils;
|
||||||
|
|
||||||
|
public static class MinioUtil
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 创建新的桶,如果不存在则创建
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bucketName">桶名称</param>
|
||||||
|
public static async Task MakeBucketAsync(string bucketName)
|
||||||
|
{
|
||||||
|
// 判断桶名称是否初始化
|
||||||
|
bucketName = bucketName.IsNullOrEmpty() ? MinioContext.BucketName : bucketName;
|
||||||
|
// minio客户端
|
||||||
|
var minioClient = MinioContext.MinioClient;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var found = await BucketExistsAsync(bucketName);
|
||||||
|
if (!found) await minioClient!.MakeBucketAsync(new MakeBucketArgs().WithBucket(bucketName));
|
||||||
|
}
|
||||||
|
catch (MinioException e)
|
||||||
|
{
|
||||||
|
Console.WriteLine(e);
|
||||||
|
throw new BunnyException(ExceptionConstant.FileSystemException);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 列出所有的桶
|
||||||
|
/// </summary>
|
||||||
|
public static async Task<ListAllMyBucketsResult> ListBucketsAsync()
|
||||||
|
{
|
||||||
|
var minioClient = MinioContext.MinioClient;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var listAllMyBucketsResult = await minioClient!.ListBucketsAsync();
|
||||||
|
return listAllMyBucketsResult;
|
||||||
|
}
|
||||||
|
catch (MinioException e)
|
||||||
|
{
|
||||||
|
Console.WriteLine(e);
|
||||||
|
throw new BunnyException(ExceptionConstant.FileSystemException);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 判断桶是否存在
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bucketName"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static async Task<bool> BucketExistsAsync(string bucketName)
|
||||||
|
{
|
||||||
|
// 判断桶名称是否初始化
|
||||||
|
bucketName = bucketName.IsNullOrEmpty() ? MinioContext.BucketName : bucketName;
|
||||||
|
// minio客户端
|
||||||
|
var minioClient = MinioContext.MinioClient;
|
||||||
|
|
||||||
|
return await minioClient!.BucketExistsAsync(new BucketExistsArgs().WithBucket(bucketName));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 移出桶
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bucketName">桶名称</param>
|
||||||
|
public static async Task RemoveBucketAsync(string bucketName)
|
||||||
|
{
|
||||||
|
// 判断桶名称是否初始化
|
||||||
|
bucketName = bucketName.IsNullOrEmpty() ? MinioContext.BucketName : bucketName;
|
||||||
|
// minio客户端
|
||||||
|
var minioClient = MinioContext.MinioClient!;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 如果存在则移除
|
||||||
|
var found = await BucketExistsAsync(bucketName);
|
||||||
|
if (found) await minioClient.RemoveBucketAsync(new RemoveBucketArgs().WithBucket(bucketName));
|
||||||
|
else Console.WriteLine("桶不存在");
|
||||||
|
}
|
||||||
|
catch (MinioException e)
|
||||||
|
{
|
||||||
|
Console.WriteLine(e);
|
||||||
|
throw new BunnyException(ExceptionConstant.FileSystemException);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查看桶的版本信息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bucketName">桶名称</param>
|
||||||
|
public static async Task<VersioningConfiguration> GetVersioningInfoAsync(string bucketName)
|
||||||
|
{
|
||||||
|
// 判断桶名称是否初始化
|
||||||
|
bucketName = bucketName.IsNullOrEmpty() ? MinioContext.BucketName : bucketName;
|
||||||
|
// minio客户端
|
||||||
|
var minioClient = MinioContext.MinioClient!;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var found = await BucketExistsAsync(bucketName);
|
||||||
|
if (!found) Console.WriteLine("桶不存在");
|
||||||
|
|
||||||
|
return await minioClient.GetVersioningAsync(new GetVersioningArgs().WithBucket(bucketName));
|
||||||
|
}
|
||||||
|
catch (MinioException e)
|
||||||
|
{
|
||||||
|
Console.WriteLine(e);
|
||||||
|
throw new BunnyException(ExceptionConstant.FileSystemException);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 上传文件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bucketName">桶名称</param>
|
||||||
|
/// <param name="file">文件</param>
|
||||||
|
public static async Task PutObjectAsync(IFormFile file, string? bucketName = default)
|
||||||
|
{
|
||||||
|
// 判断桶名称是否初始化
|
||||||
|
bucketName = bucketName.IsNullOrEmpty() ? MinioContext.BucketName : bucketName;
|
||||||
|
// minio客户端
|
||||||
|
var minioClient = MinioContext.MinioClient!;
|
||||||
|
|
||||||
|
var guid = Guid.NewGuid().ToString();
|
||||||
|
var fileName = guid + file.FileName;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var found = await BucketExistsAsync(bucketName!);
|
||||||
|
if (!found) await MakeBucketAsync(bucketName!);
|
||||||
|
|
||||||
|
await minioClient.PutObjectAsync(new PutObjectArgs().WithBucket(bucketName).WithObject(fileName)
|
||||||
|
.WithStreamData(file.OpenReadStream()).WithObjectSize(file.Length));
|
||||||
|
}
|
||||||
|
catch (MinioException e)
|
||||||
|
{
|
||||||
|
Console.WriteLine(e);
|
||||||
|
throw new BunnyException(ExceptionConstant.FileSystemException);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取文件对象信息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bucketName">桶名称</param>
|
||||||
|
/// <param name="filename">文件名</param>
|
||||||
|
public static async Task<ObjectStat> GetObjectAsync(string filename, string? bucketName = default)
|
||||||
|
{
|
||||||
|
// 判断桶名称是否初始化
|
||||||
|
bucketName = bucketName.IsNullOrEmpty() ? MinioContext.BucketName : bucketName;
|
||||||
|
// minio客户端
|
||||||
|
var minioClient = MinioContext.MinioClient!;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var statObjectArgs = new StatObjectArgs().WithBucket(bucketName).WithObject(filename);
|
||||||
|
await minioClient.StatObjectAsync(statObjectArgs);
|
||||||
|
|
||||||
|
var getObjectArgs = new GetObjectArgs().WithBucket(bucketName).WithObject(filename).WithFile(filename);
|
||||||
|
return await minioClient.GetObjectAsync(getObjectArgs);
|
||||||
|
}
|
||||||
|
catch (MinioException e)
|
||||||
|
{
|
||||||
|
Console.WriteLine(e);
|
||||||
|
throw new BunnyException(ExceptionConstant.FileSystemException);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 桶中内容状态
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bucketName">桶名称</param>
|
||||||
|
/// <param name="filename">文件名</param>
|
||||||
|
public static async Task<ObjectStat> StatObject(string filename, string? bucketName = default)
|
||||||
|
{
|
||||||
|
// 判断桶名称是否初始化
|
||||||
|
bucketName = bucketName.IsNullOrEmpty() ? MinioContext.BucketName : bucketName;
|
||||||
|
// minio客户端
|
||||||
|
var minioClient = MinioContext.MinioClient!;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Get the metadata of the object.
|
||||||
|
var statObjectArgs = new StatObjectArgs()
|
||||||
|
.WithBucket(bucketName)
|
||||||
|
.WithObject(filename);
|
||||||
|
var objectStat = await minioClient.StatObjectAsync(statObjectArgs);
|
||||||
|
return objectStat;
|
||||||
|
}
|
||||||
|
catch (MinioException e)
|
||||||
|
{
|
||||||
|
Console.WriteLine(e);
|
||||||
|
throw new BunnyException(ExceptionConstant.FileSystemException);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,6 +9,7 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Fleck" Version="1.2.0"/>
|
<PackageReference Include="Fleck" Version="1.2.0"/>
|
||||||
<PackageReference Include="Lazy.Captcha.Core" Version="2.0.8"/>
|
<PackageReference Include="Lazy.Captcha.Core" Version="2.0.8"/>
|
||||||
|
<PackageReference Include="Quartz" Version="3.13.0"/>
|
||||||
<PackageReference Include="Quartz.Extensions.Hosting" Version="3.13.0"/>
|
<PackageReference Include="Quartz.Extensions.Hosting" Version="3.13.0"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
namespace Bunny.Service.IService;
|
||||||
|
|
||||||
|
public interface IJobService
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 开启一个简单的工作
|
||||||
|
/// </summary>
|
||||||
|
void StartSimpleJob();
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
using Bunny.Service.Job;
|
||||||
|
using Quartz;
|
||||||
|
using Quartz.Impl;
|
||||||
|
|
||||||
|
namespace Bunny.Service.IService.Service;
|
||||||
|
|
||||||
|
public class JobService : IJobService
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 开启一个简单的工作
|
||||||
|
/// https://www.youtube.com/watch?v=CuHIScZKup8&list=PLSi1BNmQ61ZohCcl43UdAksg7X3_TSmly&index=6
|
||||||
|
/// </summary>
|
||||||
|
public void StartSimpleJob()
|
||||||
|
{
|
||||||
|
var schedulerFactory = new StdSchedulerFactory();
|
||||||
|
// TODO 如果使用异步,必须使用await 和 async
|
||||||
|
// var scheduler = schedulerFactory.GetScheduler();
|
||||||
|
var scheduler = schedulerFactory.GetScheduler().GetAwaiter().GetResult();
|
||||||
|
|
||||||
|
var jobDetail = JobBuilder.Create<SimJob>()
|
||||||
|
.UsingJobData("username", "用户名")
|
||||||
|
.UsingJobData("password", "密码")
|
||||||
|
.WithIdentity("simpleJob", "简单的JOB")
|
||||||
|
.Build();
|
||||||
|
var trigger = TriggerBuilder.Create()
|
||||||
|
.WithIdentity("testTrigger", "测试发出器")
|
||||||
|
.StartNow()
|
||||||
|
// 每隔5秒执行一次,一共重复10次
|
||||||
|
.WithSimpleSchedule(x => x.WithIntervalInSeconds(5).WithRepeatCount(10))
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
// 使用同步方法
|
||||||
|
scheduler.ScheduleJob(jobDetail, trigger).GetAwaiter().GetResult();
|
||||||
|
scheduler.Start().GetAwaiter().GetResult();
|
||||||
|
|
||||||
|
// TODO 使用异步
|
||||||
|
// await _scheduler.ScheduleJob(jobDetail, trigger);
|
||||||
|
// await _scheduler.Start();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
using Quartz;
|
||||||
|
|
||||||
|
namespace Bunny.Service.Job;
|
||||||
|
|
||||||
|
public class SimJob : IJob
|
||||||
|
{
|
||||||
|
public Task Execute(IJobExecutionContext context)
|
||||||
|
{
|
||||||
|
Console.WriteLine("执行一个简单的任务");
|
||||||
|
var dataMap = context.JobDetail.JobDataMap;
|
||||||
|
var username = dataMap.GetString("username");
|
||||||
|
var password = dataMap.GetString("password");
|
||||||
|
Console.WriteLine($"用户名:{username},密码: {password}");
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,8 +1,10 @@
|
||||||
namespace Bunny.Service.WebSocket;
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
|
||||||
|
namespace Bunny.Service.WebSocket;
|
||||||
|
|
||||||
public static class WebSocketInitial
|
public static class WebSocketInitial
|
||||||
{
|
{
|
||||||
public static void Start()
|
public static void AddWebSocketInitial(this WebApplicationBuilder builder)
|
||||||
{
|
{
|
||||||
WebSocketTest.Start();
|
WebSocketTest.Start();
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,13 +44,15 @@ public class BaseConfig(WebApplicationBuilder builder)
|
||||||
private void UseExtend()
|
private void UseExtend()
|
||||||
{
|
{
|
||||||
// 设置过滤器
|
// 设置过滤器
|
||||||
FilterConfig.Initialize(builder);
|
builder.FilterConfigInitialize();
|
||||||
// 初始化Redis
|
// 初始化Redis
|
||||||
RedisContext.Initial();
|
builder.AddRedisContext();
|
||||||
|
// 初始化Minio
|
||||||
|
builder.AddMinioContext();
|
||||||
// 初始化 Knife4Net 文档
|
// 初始化 Knife4Net 文档
|
||||||
Knife4Net.Initialize(builder);
|
builder.AddKnife4Net();
|
||||||
// 启动 webSocket
|
// 启动 webSocket
|
||||||
WebSocketInitial.Start();
|
builder.AddWebSocketInitial();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -9,7 +9,7 @@ public static class FilterConfig
|
||||||
/// 配置过滤器
|
/// 配置过滤器
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="builder"></param>
|
/// <param name="builder"></param>
|
||||||
public static void Initialize(WebApplicationBuilder builder)
|
public static void FilterConfigInitialize(this WebApplicationBuilder builder)
|
||||||
{
|
{
|
||||||
// 添加自定义过滤器---全局异常捕获
|
// 添加自定义过滤器---全局异常捕获
|
||||||
builder.Services.AddControllers(option =>
|
builder.Services.AddControllers(option =>
|
||||||
|
|
|
@ -8,7 +8,7 @@ public static class Knife4Net
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 配置 Knife4j 文档
|
/// 配置 Knife4j 文档
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void Initialize(WebApplicationBuilder builder)
|
public static void AddKnife4Net(this WebApplicationBuilder builder)
|
||||||
{
|
{
|
||||||
builder.Services.AddEndpointsApiExplorer();
|
builder.Services.AddEndpointsApiExplorer();
|
||||||
builder.Services.AddSwaggerGen(options =>
|
builder.Services.AddSwaggerGen(options =>
|
||||||
|
|
|
@ -15,6 +15,7 @@ public static class ServiceRegistration
|
||||||
builder.Services.AddScoped<IBaseService, BaseService>();
|
builder.Services.AddScoped<IBaseService, BaseService>();
|
||||||
builder.Services.AddScoped<IBlogService, BlogService>();
|
builder.Services.AddScoped<IBlogService, BlogService>();
|
||||||
builder.Services.AddScoped<IRedisOptionService, RedisOptionService>();
|
builder.Services.AddScoped<IRedisOptionService, RedisOptionService>();
|
||||||
|
builder.Services.AddScoped<IJobService, JobService>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
using Bunny.Dao.Result;
|
||||||
|
using Bunny.Service.IService;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace Bunny.WebApi.Controllers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Quartz 示例相关
|
||||||
|
/// </summary>
|
||||||
|
[Route("/api/[controller]/[action]")]
|
||||||
|
public class JobInitController(IJobService jobService) : ControllerBase
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 开启一个简单的工作
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost]
|
||||||
|
public Result<string> StartSimpleJob()
|
||||||
|
{
|
||||||
|
jobService.StartSimpleJob();
|
||||||
|
return Result<string>.Success();
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,5 +21,11 @@
|
||||||
"Password": "02120212",
|
"Password": "02120212",
|
||||||
"DefaultDB": 6,
|
"DefaultDB": 6,
|
||||||
"AsyncTimeout": 300
|
"AsyncTimeout": 300
|
||||||
|
},
|
||||||
|
"Minio": {
|
||||||
|
"Url": "192.168.3.98:9000",
|
||||||
|
"AccessKey": "bunny",
|
||||||
|
"SecretKey": "02120212",
|
||||||
|
"BucketName": "test"
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue