176 lines
5.7 KiB
C#
176 lines
5.7 KiB
C#
using FellowOakDicom.Network;
|
|
using FellowOakDicom;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.Extensions.Logging;
|
|
using IRaCIS.Core.Application.Contracts.Dicom;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Hosting;
|
|
|
|
namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
|
{
|
|
/// <summary>
|
|
/// 后台托管服务的方式运行
|
|
/// </summary>
|
|
public class CStoreSCPHostedService : IHostedService
|
|
{
|
|
private readonly ILogger<CStoreSCPHostedService> _logger;
|
|
private readonly IDicomServerFactory _dicomServerFactory;
|
|
private IDicomServer? _server;
|
|
|
|
public CStoreSCPHostedService(ILogger<CStoreSCPHostedService> logger, IDicomServerFactory dicomServerFactory)
|
|
{
|
|
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
|
_dicomServerFactory = dicomServerFactory ?? throw new ArgumentNullException(nameof(dicomServerFactory));
|
|
}
|
|
|
|
public async Task StartAsync(CancellationToken cancellationToken)
|
|
{
|
|
_logger.LogInformation("Starting DICOM server");
|
|
_server = _dicomServerFactory.Create<CStoreSCPService>(104);
|
|
_logger.LogInformation("DICOM server is running");
|
|
}
|
|
|
|
public Task StopAsync(CancellationToken cancellationToken)
|
|
{
|
|
if (_server != null)
|
|
{
|
|
_server.Stop();
|
|
_server.Dispose();
|
|
_server = null;
|
|
}
|
|
return Task.CompletedTask;
|
|
}
|
|
}
|
|
|
|
|
|
public class CStoreSCPService : DicomService, IDicomServiceProvider, IDicomCStoreProvider, IDicomCEchoProvider
|
|
{
|
|
private IServiceProvider _serviceProvider { get; set; }
|
|
|
|
|
|
private static readonly DicomTransferSyntax[] _acceptedTransferSyntaxes = new DicomTransferSyntax[]
|
|
{
|
|
DicomTransferSyntax.ExplicitVRLittleEndian,
|
|
DicomTransferSyntax.ExplicitVRBigEndian,
|
|
DicomTransferSyntax.ImplicitVRLittleEndian
|
|
};
|
|
|
|
private static readonly DicomTransferSyntax[] _acceptedImageTransferSyntaxes = new DicomTransferSyntax[]
|
|
{
|
|
// Lossless
|
|
DicomTransferSyntax.JPEGLSLossless,
|
|
DicomTransferSyntax.JPEG2000Lossless,
|
|
DicomTransferSyntax.JPEGProcess14SV1,
|
|
DicomTransferSyntax.JPEGProcess14,
|
|
DicomTransferSyntax.RLELossless,
|
|
// Lossy
|
|
DicomTransferSyntax.JPEGLSNearLossless,
|
|
DicomTransferSyntax.JPEG2000Lossy,
|
|
DicomTransferSyntax.JPEGProcess1,
|
|
DicomTransferSyntax.JPEGProcess2_4,
|
|
// Uncompressed
|
|
DicomTransferSyntax.ExplicitVRLittleEndian,
|
|
DicomTransferSyntax.ExplicitVRBigEndian,
|
|
DicomTransferSyntax.ImplicitVRLittleEndian
|
|
};
|
|
|
|
|
|
public CStoreSCPService(INetworkStream stream, Encoding fallbackEncoding, ILogger log, DicomServiceDependencies dependencies)
|
|
: base(stream, fallbackEncoding, log, dependencies)
|
|
{
|
|
var tt = base.UserState;
|
|
//_dicomArchiveService = dicomArchiveService;
|
|
}
|
|
|
|
|
|
|
|
|
|
public Task OnReceiveAssociationRequestAsync(DicomAssociation association)
|
|
{
|
|
_serviceProvider =(IServiceProvider) this.UserState;
|
|
|
|
if (association.CalledAE != "STORESCP")
|
|
{
|
|
return SendAssociationRejectAsync(
|
|
DicomRejectResult.Permanent,
|
|
DicomRejectSource.ServiceUser,
|
|
DicomRejectReason.CalledAENotRecognized);
|
|
}
|
|
|
|
foreach (var pc in association.PresentationContexts)
|
|
{
|
|
if (pc.AbstractSyntax == DicomUID.Verification)
|
|
{
|
|
pc.AcceptTransferSyntaxes(_acceptedTransferSyntaxes);
|
|
}
|
|
else if (pc.AbstractSyntax.StorageCategory != DicomStorageCategory.None)
|
|
{
|
|
pc.AcceptTransferSyntaxes(_acceptedImageTransferSyntaxes);
|
|
}
|
|
}
|
|
|
|
return SendAssociationAcceptAsync(association);
|
|
}
|
|
|
|
|
|
public Task OnReceiveAssociationReleaseRequestAsync()
|
|
{
|
|
return SendAssociationReleaseResponseAsync();
|
|
}
|
|
|
|
|
|
public void OnReceiveAbort(DicomAbortSource source, DicomAbortReason reason)
|
|
{
|
|
/* nothing to do here */
|
|
}
|
|
|
|
|
|
public void OnConnectionClosed(Exception exception)
|
|
{
|
|
/* nothing to do here */
|
|
}
|
|
|
|
|
|
public async Task<DicomCStoreResponse> OnCStoreRequestAsync(DicomCStoreRequest request)
|
|
{
|
|
var tt= _serviceProvider.GetService<IDicomArchiveService>();
|
|
|
|
var studyUid = request.Dataset.GetSingleValue<string>(DicomTag.StudyInstanceUID).Trim();
|
|
var instUid = request.SOPInstanceUID.UID;
|
|
|
|
var path = Path.GetFullPath(@".\DICOM-Store");
|
|
|
|
path = Path.Combine(path, studyUid);
|
|
|
|
if (!Directory.Exists(path))
|
|
{
|
|
Directory.CreateDirectory(path);
|
|
}
|
|
|
|
path = Path.Combine(path, instUid) + ".dcm";
|
|
|
|
await request.File.SaveAsync(path);
|
|
|
|
return new DicomCStoreResponse(request, DicomStatus.Success);
|
|
}
|
|
|
|
|
|
public Task OnCStoreRequestExceptionAsync(string tempFileName, Exception e)
|
|
{
|
|
// let library handle logging and error response
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
|
|
public Task<DicomCEchoResponse> OnCEchoRequestAsync(DicomCEchoRequest request)
|
|
{
|
|
return Task.FromResult(new DicomCEchoResponse(request, DicomStatus.Success));
|
|
}
|
|
|
|
}
|
|
}
|