新增文件传输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>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Services\FileTransferService.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Protobuf Include="Protos\greet.proto" GrpcServices="Both" />
|
||||
<Protobuf Include="Protos\block.proto" GrpcServices="Client" />
|
||||
<Protobuf Include="Protos\my_diary.proto" GrpcServices="Server" />
|
||||
<Protobuf Include="Protos\FileTransfer.proto" GrpcServices="Server" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user