109 lines
4.2 KiB
C#
109 lines
4.2 KiB
C#
using Grpc.Core;
|
|
using ZR.Admin.Grpc;
|
|
|
|
namespace GrpcService.Services
|
|
{
|
|
public class FileTransferService : FileTransfer.FileTransferBase
|
|
{
|
|
private readonly string _storagePath = "Îļþ";
|
|
private readonly IUploadSessionManager _sessionManager;
|
|
|
|
public FileTransferService(IUploadSessionManager sessionManager)
|
|
{
|
|
Directory.CreateDirectory(_storagePath);
|
|
_sessionManager = sessionManager;
|
|
}
|
|
|
|
public override Task<InitUploadResponse> InitUpload(InitUploadRequest request, ServerCallContext context)
|
|
{
|
|
var sessionId = _sessionManager.CreateSession(request.FileName, request.FileSize, request.FileHash);
|
|
var uploadedBytes = _sessionManager.GetUploadedBytes(sessionId);
|
|
|
|
return Task.FromResult(new InitUploadResponse
|
|
{
|
|
SessionId = sessionId,
|
|
UploadedBytes = uploadedBytes
|
|
});
|
|
}
|
|
|
|
public override async Task<UploadChunkResponse> UploadChunk(IAsyncStreamReader<UploadChunkRequest> requestStream, ServerCallContext context)
|
|
{
|
|
UploadChunkRequest currentRequest = null;
|
|
var response = new UploadChunkResponse();
|
|
|
|
while (await requestStream.MoveNext())
|
|
{
|
|
currentRequest = requestStream.Current;
|
|
var session = _sessionManager.GetSession(currentRequest.SessionId);
|
|
|
|
if (session == null)
|
|
{
|
|
throw new RpcException(new Status(StatusCode.NotFound, "Session not found"));
|
|
}
|
|
|
|
using (var fileStream = new FileStream(session.TempFilePath, FileMode.OpenOrCreate, FileAccess.Write))
|
|
{
|
|
fileStream.Seek(currentRequest.Offset, SeekOrigin.Begin);
|
|
await fileStream.WriteAsync(currentRequest.ChunkData.ToByteArray(), 0, currentRequest.ChunkData.Length);
|
|
}
|
|
|
|
_sessionManager.UpdateSessionProgress(currentRequest.SessionId, currentRequest.Offset + currentRequest.ChunkData.Length);
|
|
response.UploadedBytes = currentRequest.Offset + currentRequest.ChunkData.Length;
|
|
}
|
|
|
|
return response;
|
|
}
|
|
|
|
public override async Task<CompleteUploadResponse> CompleteUpload(CompleteUploadRequest request, ServerCallContext context)
|
|
{
|
|
var session = _sessionManager.GetSession(request.SessionId);
|
|
if (session == null)
|
|
{
|
|
return await Task.FromResult(new CompleteUploadResponse
|
|
{
|
|
Success = false,
|
|
Message = "Session not found"
|
|
});
|
|
}
|
|
|
|
// Verify file hash if needed
|
|
if (!string.IsNullOrEmpty(request.FileHash))
|
|
{
|
|
var actualHash = await FileHelper.GetQuickFileIdentity(session.TempFilePath);
|
|
if (actualHash != request.FileHash)
|
|
{
|
|
return await Task.FromResult(new CompleteUploadResponse
|
|
{
|
|
Success = false,
|
|
Message = "File hash mismatch"
|
|
});
|
|
}
|
|
}
|
|
|
|
// Move temp file to final location
|
|
var finalPath = Path.Combine(_storagePath, session.FileName);
|
|
//var finalPath = FileHelper.GetUniqueFilePath(_storagePath, session.FileName);
|
|
File.Move(session.TempFilePath, finalPath, true);
|
|
|
|
_sessionManager.CompleteSession(request.SessionId);
|
|
|
|
return await Task.FromResult(new CompleteUploadResponse
|
|
{
|
|
Success = true,
|
|
Message = "File uploaded successfully"
|
|
});
|
|
}
|
|
|
|
public override Task<CheckUploadStatusResponse> CheckUploadStatus(CheckUploadStatusRequest request, ServerCallContext context)
|
|
{
|
|
var session = _sessionManager.FindSession(request.FileName, request.FileHash);
|
|
|
|
return Task.FromResult(new CheckUploadStatusResponse
|
|
{
|
|
SessionId = session?.SessionId ?? "",
|
|
UploadedBytes = session?.UploadedBytes ?? 0,
|
|
Exists = session != null
|
|
});
|
|
}
|
|
}
|
|
} |