diff --git a/IRC.Core.SCP/Service/CStoreSCPService.cs b/IRC.Core.SCP/Service/CStoreSCPService.cs index 2a06c1575..918b49764 100644 --- a/IRC.Core.SCP/Service/CStoreSCPService.cs +++ b/IRC.Core.SCP/Service/CStoreSCPService.cs @@ -334,36 +334,36 @@ namespace IRaCIS.Core.SCP.Service { _isCurrentThirdForward = true; - var _dicomAERepository = _serviceProvider.GetService>(); - var hirServer = await _dicomAERepository.FirstOrDefaultAsync(t => t.PacsTypeEnum == PacsType.HIRServer); - - try + _ = Task.Run(async () => { - var findDestination = DicomSCPServiceConfig.ThirdDestinationAEList.FirstOrDefault(t => t.Name == cmoveInfo.DestinationAE); - - 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) => + try { - 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); - await client.SendAsync(); - } - catch (Exception ex) - { - Log.Logger.Error("Error forwarding C-STORE: " + ex.Message); - } + // 创建客户端连接到目标 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); } } diff --git a/IRC.Core.SCP/appsettings.Test_HIR_SCP.json b/IRC.Core.SCP/appsettings.Test_HIR_SCP.json index a4e8f751d..bdb7c3131 100644 --- a/IRC.Core.SCP/appsettings.Test_HIR_SCP.json +++ b/IRC.Core.SCP/appsettings.Test_HIR_SCP.json @@ -34,13 +34,10 @@ }, { "Name": "HIRLAE", - "IP": "106.14.89.110", + "IP": "192.168.3.194", "Port": "6000" } - ] - - - + ], "CalledAEList": [ "HIRAE", "STORESCP" diff --git a/IRaCIS.Core.API/HostService/DicomSCPService.cs b/IRaCIS.Core.API/HostService/DicomSCPService.cs index ba514b1e2..050957873 100644 --- a/IRaCIS.Core.API/HostService/DicomSCPService.cs +++ b/IRaCIS.Core.API/HostService/DicomSCPService.cs @@ -14,6 +14,7 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Text; +using System.Threading; using System.Threading.Channels; using System.Threading.Tasks; @@ -83,7 +84,7 @@ namespace IRaCIS.Core.API.HostService public void OnConnectionClosed(Exception exception) { - if (exception != null) + if (exception != null) { 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..."); + var cts = new CancellationTokenSource(); + var _dicomAERepository = _serviceProvider.GetService>(); 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) { 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 }; + var receivedCount = 0; + // 标记是否已收到 final 状态(Success/Failure/Cancel) var finalReceived = false; // 当远端 PACS 返回响应时,异步写入 channel 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 proxyResp = new DicomCFindResponse(request, rp.Status) { @@ -199,26 +237,23 @@ namespace IRaCIS.Core.API.HostService // 异步发送到真实 PACS - - try + _ = Task.Run(async () => { - var client = DicomClientFactory.Create(find.IP, find.Port, false, hirClient.CalledAE, find.CalledAE); - await client.AddRequestAsync(forward); - await client.SendAsync(); - } - catch (Exception ex) - { - Console.WriteLine("Error forwarding C-FIND: " + ex.Message); - } - finally - { - channel.Writer.Complete(); - } - - //_ = Task.Run(async () => - //{ - - //}); + try + { + var client = DicomClientFactory.Create(find.IP, find.Port, false, hirClient.CalledAE, find.CalledAE); + await client.AddRequestAsync(forward); + await client.SendAsync(cancellationToken: cts.Token); + } + catch (Exception ex) + { + Console.WriteLine("Error forwarding C-FIND: " + ex.Message); + } + finally + { + channel.Writer.Complete(); + } + }); // 异步 yield 返回给上游 await foreach (var resp in channel.Reader.ReadAllAsync()) @@ -283,39 +318,43 @@ namespace IRaCIS.Core.API.HostService Dataset = dsCopy, Remaining = rp.Remaining, Completed = rp.Completed, + Failures = rp.Failures, + Warnings = rp.Warnings, }; + Logger.LogInformation($"Completed:{rp.Completed}"); + channel.Writer.TryWrite(proxyResp); if (!rp.Status.Equals(DicomStatus.Pending)) { finalReceived = true; } + + }; - // 异步发送到真实 PACS - try + // 异步发送到真实 PACS + _ = Task.Run(async () => { - var client = DicomClientFactory.Create(find.IP, find.Port, false, hirClient.CalledAE, find.CalledAE); - await client.AddRequestAsync(forward); - await client.SendAsync(); - } - catch (Exception ex) - { - Console.WriteLine("Error forwarding C-MOVE: " + ex.Message); - } - finally - { - channel.Writer.Complete(); - } - - //_ = Task.Run(async () => - //{ - - //}); + try + { + var client = DicomClientFactory.Create(find.IP, find.Port, false, hirClient.CalledAE, find.CalledAE); + await client.AddRequestAsync(forward); + await client.SendAsync(); + } + catch (Exception ex) + { + Console.WriteLine("Error forwarding C-MOVE: " + ex.Message); + } + finally + { + channel.Writer.Complete(); + } + }); // 异步 yield 回上游 await foreach (var resp in channel.Reader.ReadAllAsync())