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 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 UploadChunk(IAsyncStreamReader 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 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 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 }); } } }