限制不能空条件查询
continuous-integration/drone/push Build is passing Details

Test_HIR_Net8
hang 2025-10-28 18:03:15 +08:00
parent aed778bbc6
commit 3328c18279
3 changed files with 103 additions and 67 deletions

View File

@ -334,36 +334,36 @@ namespace IRaCIS.Core.SCP.Service
{ {
_isCurrentThirdForward = true; _isCurrentThirdForward = true;
var _dicomAERepository = _serviceProvider.GetService<IRepository<DicomAE>>(); _ = Task.Run(async () =>
var hirServer = await _dicomAERepository.FirstOrDefaultAsync(t => t.PacsTypeEnum == PacsType.HIRServer);
try
{ {
var findDestination = DicomSCPServiceConfig.ThirdDestinationAEList.FirstOrDefault(t => t.Name == cmoveInfo.DestinationAE); try
var forwardRequest = new DicomCStoreRequest(request.File.Clone());
// 创建客户端连接到目标 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}"); var findDestination = DicomSCPServiceConfig.ThirdDestinationAEList.FirstOrDefault(t => t.Name == cmoveInfo.DestinationAE);
}; var forwardRequest = new DicomCStoreRequest(request.File.Clone());
await client.AddRequestAsync(forwardRequest); // 创建客户端连接到目标 PACS
await client.SendAsync(); var client = DicomClientFactory.Create(findDestination.IP, findDestination.Port, false, DicomSCPServiceConfig.CalledAEList.First(), cmoveInfo.DestinationAE);
}
catch (Exception ex)
{
Log.Logger.Error("Error forwarding C-STORE: " + ex.Message);
}
// 可以加入 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); return new DicomCStoreResponse(request, DicomStatus.Success);
} }
} }

View File

@ -34,13 +34,10 @@
}, },
{ {
"Name": "HIRLAE", "Name": "HIRLAE",
"IP": "106.14.89.110", "IP": "192.168.3.194",
"Port": "6000" "Port": "6000"
} }
] ],
"CalledAEList": [ "CalledAEList": [
"HIRAE", "HIRAE",
"STORESCP" "STORESCP"

View File

@ -14,6 +14,7 @@ using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using System.Threading;
using System.Threading.Channels; using System.Threading.Channels;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -83,7 +84,7 @@ namespace IRaCIS.Core.API.HostService
public void OnConnectionClosed(Exception exception) public void OnConnectionClosed(Exception exception)
{ {
if (exception != null) if (exception != null)
{ {
Logger.LogError($"Closed, exception is {exception.Message}"); Logger.LogError($"Closed, exception is {exception.Message}");
} }
@ -155,6 +156,8 @@ namespace IRaCIS.Core.API.HostService
{ {
Console.WriteLine("Received C-FIND request, forwarding to real PACS..."); Console.WriteLine("Received C-FIND request, forwarding to real PACS...");
var cts = new CancellationTokenSource();
var _dicomAERepository = _serviceProvider.GetService<IRepository<DicomAE>>(); var _dicomAERepository = _serviceProvider.GetService<IRepository<DicomAE>>();
var find = await _dicomAERepository.FirstOrDefaultAsync(t => t.PacsTypeEnum == PacsType.PacsServer && t.CalledAE == DicomSCPServiceConfig.ThirdSearchPacsAE); var find = await _dicomAERepository.FirstOrDefaultAsync(t => t.PacsTypeEnum == PacsType.PacsServer && t.CalledAE == DicomSCPServiceConfig.ThirdSearchPacsAE);
@ -165,6 +168,21 @@ namespace IRaCIS.Core.API.HostService
if (find == null || hirClient == null) if (find == null || hirClient == null)
{ {
Logger.LogInformation("客户端和Pacs配置未查询到"); Logger.LogInformation("客户端和Pacs配置未查询到");
yield return new DicomCFindResponse(request, DicomStatus.ProcessingFailure);
yield break;
}
string patientID = request.Dataset.GetSingleValueOrDefault(DicomTag.PatientID, string.Empty);
string patientName = request.Dataset.GetSingleValueOrDefault(DicomTag.PatientName, string.Empty);
string studyDate = request.Dataset.GetSingleValueOrDefault(DicomTag.StudyDate, string.Empty);
string studyInstanceUID = request.Dataset.GetSingleValueOrDefault(DicomTag.StudyInstanceUID, string.Empty);
if (patientID.IsNullOrEmpty() && patientName.IsNullOrEmpty() && studyInstanceUID.IsNullOrEmpty() && studyDate.IsNullOrEmpty())
{
yield return new DicomCFindResponse(request, DicomStatus.MissingAttribute);
yield break;
} }
@ -178,12 +196,32 @@ namespace IRaCIS.Core.API.HostService
Dataset = clonedDataset Dataset = clonedDataset
}; };
var receivedCount = 0;
// 标记是否已收到 final 状态Success/Failure/Cancel // 标记是否已收到 final 状态Success/Failure/Cancel
var finalReceived = false; var finalReceived = false;
// 当远端 PACS 返回响应时,异步写入 channel // 当远端 PACS 返回响应时,异步写入 channel
forward.OnResponseReceived += (rq, rp) => forward.OnResponseReceived += (rq, rp) =>
{ {
#region 取消,现在不行
////100条的时候直接取消
//if (receivedCount >= 10)
//{
// rp.Status = DicomStatus.Cancel;
// cts.Cancel(); // 触发取消
// Logger.LogWarning("超过100条剩余的取消!");
//}
//receivedCount++;
#endregion
var dsCopy = rp.Dataset?.Clone(); var dsCopy = rp.Dataset?.Clone();
var proxyResp = new DicomCFindResponse(request, rp.Status) var proxyResp = new DicomCFindResponse(request, rp.Status)
{ {
@ -199,26 +237,23 @@ namespace IRaCIS.Core.API.HostService
// 异步发送到真实 PACS // 异步发送到真实 PACS
_ = Task.Run(async () =>
try
{ {
var client = DicomClientFactory.Create(find.IP, find.Port, false, hirClient.CalledAE, find.CalledAE); try
await client.AddRequestAsync(forward); {
await client.SendAsync(); var client = DicomClientFactory.Create(find.IP, find.Port, false, hirClient.CalledAE, find.CalledAE);
} await client.AddRequestAsync(forward);
catch (Exception ex) await client.SendAsync(cancellationToken: cts.Token);
{ }
Console.WriteLine("Error forwarding C-FIND: " + ex.Message); catch (Exception ex)
} {
finally Console.WriteLine("Error forwarding C-FIND: " + ex.Message);
{ }
channel.Writer.Complete(); finally
} {
channel.Writer.Complete();
//_ = Task.Run(async () => }
//{ });
//});
// 异步 yield 返回给上游 // 异步 yield 返回给上游
await foreach (var resp in channel.Reader.ReadAllAsync()) await foreach (var resp in channel.Reader.ReadAllAsync())
@ -283,39 +318,43 @@ namespace IRaCIS.Core.API.HostService
Dataset = dsCopy, Dataset = dsCopy,
Remaining = rp.Remaining, Remaining = rp.Remaining,
Completed = rp.Completed, Completed = rp.Completed,
Failures = rp.Failures,
Warnings = rp.Warnings,
}; };
Logger.LogInformation($"Completed:{rp.Completed}"); Logger.LogInformation($"Completed:{rp.Completed}");
channel.Writer.TryWrite(proxyResp); channel.Writer.TryWrite(proxyResp);
if (!rp.Status.Equals(DicomStatus.Pending)) if (!rp.Status.Equals(DicomStatus.Pending))
{ {
finalReceived = true; finalReceived = true;
} }
}; };
// 异步发送到真实 PACS // 异步发送到真实 PACS
try _ = Task.Run(async () =>
{ {
var client = DicomClientFactory.Create(find.IP, find.Port, false, hirClient.CalledAE, find.CalledAE); try
await client.AddRequestAsync(forward); {
await client.SendAsync(); var client = DicomClientFactory.Create(find.IP, find.Port, false, hirClient.CalledAE, find.CalledAE);
} await client.AddRequestAsync(forward);
catch (Exception ex) await client.SendAsync();
{ }
Console.WriteLine("Error forwarding C-MOVE: " + ex.Message); catch (Exception ex)
} {
finally Console.WriteLine("Error forwarding C-MOVE: " + ex.Message);
{ }
channel.Writer.Complete(); finally
} {
channel.Writer.Complete();
//_ = Task.Run(async () => }
//{ });
//});
// 异步 yield 回上游 // 异步 yield 回上游
await foreach (var resp in channel.Reader.ReadAllAsync()) await foreach (var resp in channel.Reader.ReadAllAsync())