新增文件传输gRPC

This commit is contained in:
wenyongda 2025-06-25 14:06:22 +08:00
parent a2cb96b9a7
commit f5d0e3c057
3 changed files with 168 additions and 0 deletions

View 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;
}

View 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
});
}
}
}

View File

@ -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>