新增文件传输gRPC
This commit is contained in:
parent
a2cb96b9a7
commit
f5d0e3c057
54
ZR.Admin.Grpc/Protos/FileTransfer.proto
Normal file
54
ZR.Admin.Grpc/Protos/FileTransfer.proto
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option csharp_namespace = "ZR.Admin.Grpc";
|
||||||
|
|
||||||
|
package filetransfer;
|
||||||
|
|
||||||
|
service FileTransfer {
|
||||||
|
rpc InitUpload (InitUploadRequest) returns (InitUploadResponse);
|
||||||
|
rpc UploadChunk (stream UploadChunkRequest) returns (UploadChunkResponse);
|
||||||
|
rpc CompleteUpload (CompleteUploadRequest) returns (CompleteUploadResponse);
|
||||||
|
rpc CheckUploadStatus (CheckUploadStatusRequest) returns (CheckUploadStatusResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
message InitUploadRequest {
|
||||||
|
string file_name = 1;
|
||||||
|
int64 file_size = 2;
|
||||||
|
string file_hash = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message InitUploadResponse {
|
||||||
|
string session_id = 1;
|
||||||
|
int64 uploaded_bytes = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UploadChunkRequest {
|
||||||
|
string session_id = 1;
|
||||||
|
bytes chunk_data = 2;
|
||||||
|
int64 offset = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UploadChunkResponse {
|
||||||
|
int64 uploaded_bytes = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CompleteUploadRequest {
|
||||||
|
string session_id = 1;
|
||||||
|
string file_hash = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CompleteUploadResponse {
|
||||||
|
bool success = 1;
|
||||||
|
string message = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CheckUploadStatusRequest {
|
||||||
|
string file_name = 1;
|
||||||
|
string file_hash = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CheckUploadStatusResponse {
|
||||||
|
string session_id = 1;
|
||||||
|
int64 uploaded_bytes = 2;
|
||||||
|
bool exists = 3;
|
||||||
|
}
|
||||||
109
ZR.Admin.Grpc/Services/FileTransferService.cs
Normal file
109
ZR.Admin.Grpc/Services/FileTransferService.cs
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
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
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -6,10 +6,15 @@
|
|||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Remove="Services\FileTransferService.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Protobuf Include="Protos\greet.proto" GrpcServices="Both" />
|
<Protobuf Include="Protos\greet.proto" GrpcServices="Both" />
|
||||||
<Protobuf Include="Protos\block.proto" GrpcServices="Client" />
|
<Protobuf Include="Protos\block.proto" GrpcServices="Client" />
|
||||||
<Protobuf Include="Protos\my_diary.proto" GrpcServices="Server" />
|
<Protobuf Include="Protos\my_diary.proto" GrpcServices="Server" />
|
||||||
|
<Protobuf Include="Protos\FileTransfer.proto" GrpcServices="Server" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user