修改接收转发多线程配置
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
parent
106916f7ad
commit
841f1892d4
|
|
@ -14,6 +14,7 @@ using MassTransit;
|
|||
using MassTransit.NewIdProviders;
|
||||
using Microsoft.AspNetCore.HttpOverrides;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Identity.Client;
|
||||
using Panda.DynamicWebApi;
|
||||
using Serilog;
|
||||
using Serilog.Events;
|
||||
|
|
@ -218,6 +219,9 @@ else
|
|||
|
||||
DicomSetupBuilder.UseServiceProvider(app.Services);
|
||||
|
||||
// Program.cs
|
||||
IRCAppConfig.Configuration = builder.Configuration;
|
||||
|
||||
|
||||
var logger = app.Services.GetService<Microsoft.Extensions.Logging.ILogger<Program>>();
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ using FellowOakDicom.IO.Buffer;
|
|||
using System.Diagnostics.CodeAnalysis;
|
||||
using FellowOakDicom.Network.Client;
|
||||
using MassTransit.Futures.Contracts;
|
||||
using Microsoft.Identity.Client;
|
||||
|
||||
namespace IRaCIS.Core.SCP.Service
|
||||
{
|
||||
|
|
@ -36,6 +37,10 @@ namespace IRaCIS.Core.SCP.Service
|
|||
{
|
||||
public bool IsSupportThirdService { get; set; }
|
||||
|
||||
public bool IsForwardImageMultiThread { get; set; }
|
||||
|
||||
|
||||
|
||||
public List<string> CalledAEList { get; set; }
|
||||
|
||||
public string ServerPort { get; set; }
|
||||
|
|
@ -50,6 +55,11 @@ namespace IRaCIS.Core.SCP.Service
|
|||
public string IP { get; set; }
|
||||
}
|
||||
|
||||
public static class IRCAppConfig
|
||||
{
|
||||
public static IConfiguration Configuration { get; set; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -77,6 +87,8 @@ namespace IRaCIS.Core.SCP.Service
|
|||
private List<ThirdDestinationAE> ThirdDestinationAEList { get; set; }
|
||||
|
||||
|
||||
|
||||
|
||||
private static readonly DicomTransferSyntax[] _acceptedTransferSyntaxes = new DicomTransferSyntax[]
|
||||
{
|
||||
DicomTransferSyntax.ExplicitVRLittleEndian,
|
||||
|
|
@ -103,6 +115,22 @@ namespace IRaCIS.Core.SCP.Service
|
|||
DicomTransferSyntax.ImplicitVRLittleEndian
|
||||
};
|
||||
|
||||
// 定义一个静态信号量,控制同时最多 N 个转发线程
|
||||
|
||||
private static SemaphoreSlim _forwardLimiter;
|
||||
|
||||
// ✅ 静态构造函数(只执行一次,全局初始化)
|
||||
static CStoreSCPService()
|
||||
{
|
||||
// 默认单线程
|
||||
|
||||
var maxThreads = IRCAppConfig.Configuration.GetValue<int>("DicomSCPServiceConfig:MultiThreadCount", 1);
|
||||
|
||||
_forwardLimiter = new SemaphoreSlim(maxThreads);
|
||||
|
||||
Log.Logger.Information($"初始化 DICOM 转发线程限制为: {maxThreads}");
|
||||
}
|
||||
|
||||
|
||||
public CStoreSCPService(INetworkStream stream, Encoding fallbackEncoding, Microsoft.Extensions.Logging.ILogger log, DicomServiceDependencies dependencies, IServiceProvider injectServiceProvider)
|
||||
: base(stream, fallbackEncoding, log, dependencies)
|
||||
|
|
@ -306,6 +334,43 @@ namespace IRaCIS.Core.SCP.Service
|
|||
}
|
||||
|
||||
|
||||
private async Task<DicomStatus> ForwardToThirdPartyAsync(DicomCStoreRequest request, ThirdDestinationAE findDestination)
|
||||
{
|
||||
await _forwardLimiter.WaitAsync(); // 限制并发数量
|
||||
try
|
||||
{
|
||||
var forwardRequest = new DicomCStoreRequest(request.File.Clone());
|
||||
|
||||
var client = DicomClientFactory.Create(
|
||||
findDestination.IP,
|
||||
findDestination.Port,
|
||||
false,
|
||||
DicomSCPServiceConfig.CalledAEList.First(),
|
||||
findDestination.Name);
|
||||
|
||||
DicomStatus finalStatus = DicomStatus.Success;
|
||||
|
||||
forwardRequest.OnResponseReceived += (rq, rp) =>
|
||||
{
|
||||
Log.Logger.Information($"Forwarded C-STORE Response: {rq.SOPInstanceUID} {rp.Status}");
|
||||
finalStatus = rp.Status; // 记录目标 PACS 返回状态
|
||||
};
|
||||
|
||||
await client.AddRequestAsync(forwardRequest);
|
||||
await client.SendAsync();
|
||||
|
||||
return finalStatus; // 返回实际状态
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Logger.Error("Error forwarding C-STORE: " + ex.Message);
|
||||
return DicomStatus.ProcessingFailure; // 出错返回失败状态
|
||||
}
|
||||
finally
|
||||
{
|
||||
_forwardLimiter.Release();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public async Task<DicomCStoreResponse> OnCStoreRequestAsync(DicomCStoreRequest request)
|
||||
|
|
@ -336,37 +401,24 @@ namespace IRaCIS.Core.SCP.Service
|
|||
{
|
||||
_isCurrentThirdForward = true;
|
||||
|
||||
_ = Task.Run(async () =>
|
||||
var findDestination = ThirdDestinationAEList.FirstOrDefault(t => t.Name == cmoveInfo.DestinationAE);
|
||||
|
||||
if (DicomSCPServiceConfig.IsForwardImageMultiThread)
|
||||
{
|
||||
// 多线程模式,异步执行
|
||||
_ = Task.Run(() => ForwardToThirdPartyAsync(request, findDestination));
|
||||
|
||||
try
|
||||
{
|
||||
var findDestination = ThirdDestinationAEList.FirstOrDefault(t => t.Name == cmoveInfo.DestinationAE);
|
||||
// 立即返回 Success
|
||||
return new DicomCStoreResponse(request, DicomStatus.Success);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 单线程模式,同步等待完成
|
||||
var responseStatus = await ForwardToThirdPartyAsync(request, findDestination);
|
||||
|
||||
var forwardRequest = new DicomCStoreRequest(request.File.Clone());
|
||||
return new DicomCStoreResponse(request, responseStatus);
|
||||
}
|
||||
|
||||
// 创建客户端连接到目标 PACS
|
||||
var client = DicomClientFactory.Create(findDestination.IP, findDestination.Port, false, DicomSCPServiceConfig.CalledAEList.First(), cmoveInfo.DestinationAE);
|
||||
|
||||
// 可以加入 OnResponseReceived 来处理目标 PACS 返回状态
|
||||
forwardRequest.OnResponseReceived += (rq, rp) =>
|
||||
{
|
||||
Log.Logger.Information($"Forwarded C-STORE Response: {rq.SOPInstanceUID} {rp.Status}");
|
||||
|
||||
};
|
||||
|
||||
await client.AddRequestAsync(forwardRequest);
|
||||
await client.SendAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Logger.Error("Error forwarding C-STORE: " + ex.Message);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// 立即返回 Success 给原发送方
|
||||
return new DicomCStoreResponse(request, DicomStatus.Success);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@
|
|||
},
|
||||
"DicomSCPServiceConfig": {
|
||||
"IsSupportThirdService": true,
|
||||
"IsForwardImageMultiThread": true,
|
||||
"MultiThreadCount":10,
|
||||
"CalledAEList": [
|
||||
"HIRAE",
|
||||
"STORESCP"
|
||||
|
|
|
|||
Loading…
Reference in New Issue