记录一次grpc分片上传
http api 模块
files, fileHeader, err := ctx.Request.FormFile("file")
if err != nil {
logx.ErrorContextf(newCtx, "form file not found Error, err:%s", err)
return
}
byteData := make([]byte, fileHeader.Size)
files.Read(byteData)
defer files.Close()
ctx, cancel := context.WithDeadline(ctx, time.Now().Add(10*time.Second))
defer cancel()
stream, err := g.GRunService.AppRPC.UploadFileV2(context.Background())
reader := bytes.NewReader(uploadFileReq.FileBytes)
buf := make([]byte, 1024)
for {
num, err := reader.Read(buf)
if err == io.EOF {
break
}
if err != nil {
return nil, &errorx.CodeErrorResponseContent{
Code: errorx.ErrCode("InternalError"),
Msg: "传输出现错误:" + err.Error(),
}
}
if err := stream.Send(&app.UploadFileRequest{
User: user,
FileNameUrl: uploadFileReq.FileNameUrl,
FileName: uploadFileReq.FileName,
FileType: uploadFileReq.FileType,
RecordsId: uploadFileReq.RecordsId,
FileBytes: buf[:num],
}); err != nil {
return nil, &errorx.CodeErrorResponseContent{
Code: errorx.ErrCode("InternalError"),
Msg: "Send传输出现错误:" + err.Error(),
}
}
}
res, err := stream.CloseAndRecv()
if err != nil {
return nil, &errorx.CodeErrorResponseContent{
Code: errorx.ErrCode("InternalError"),
Msg: "CloseAndRecv出现错误:" + err.Error(),
}
}
go-zero rpc模块
func (l *UserLogic) UploadFileV2(stream app.App_UploadFileV2Server) error {
var res []byte
var name *app.UploadFileRequest
for {
da, err := stream.Recv()
if da != nil && len(da.FileBytes) > 0 {
res = append(res, da.GetFileBytes()...)
}
if err == io.EOF {
newFileName := ""
if name.FileName == "" {
newFileName = fmt.Sprintf("%s_%s%s", name.User, time.Now().Local().Format("20060102150405"), name.FileType)
} else {
newFileName = name.FileName
}
var info = &upload.UploadInfo{
UserID: name.User,
FileName: newFileName,
FileType: name.FileType,
RecordsId: name.RecordsId,
FileBytes: res,
}
downloadUrl, err := upload.UploadFileV3(context.Background(), info)
if err != nil {
fmt.Println("上传图片出错,err:", err.Error())
return err
}
stream.SendAndClose(&app.UploadFileResp{
Err: nil,
DownloadURL: downloadUrl,
})
return nil
}
if err != nil {
fmt.Println("服务端 err=", err.Error())
stream.SendAndClose(&app.UploadFileResp{
Err: nil,
DownloadURL: "",
})
return err
}
name = da
}
}
func UploadFileV3(ctx context.Context, req *UploadInfo) (downloadURL string, err error) {
ossFileName := ""
if req.RecordsId == "" {
ossFileName = GetOssFileNameToManage(req)
} else {
ossFileName = GetOssFileName(req)
}
onlyFileName := fmt.Sprintf("%s%s", req.FileName, req.FileType)
downloadURL, err = oss.OssClient.UploadFileByFragmentation(ctx, ossFileName, req.FileBytes, 3, onlyFileName)
if err != nil {
return
}
return
}