golang go-zero 大文件上传 grpc分片上传

记录一次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()
	//这里调用grpc处理
	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 {
			//fmt.Println("传输出现错误:", err.Error())
			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 {
			//fmt.Println("传输出现错误222:", err.Error())
			return nil, &errorx.CodeErrorResponseContent{
				Code: errorx.ErrCode("InternalError"),
				Msg:  "Send传输出现错误:" + err.Error(),
			}
		}
	}
	res, err := stream.CloseAndRecv()
	if err != nil {
		//fmt.Println("传输出现错误333:", err.Error())
		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,
			}
			//reader := bytes.NewReader(res)
			//fmt.Println(len(res), reader.Size())
			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
	}
}



// UploadFileV3 分片上传
func UploadFileV3(ctx context.Context, req *UploadInfo) (downloadURL string, err error) {
	ossFileName := ""        // 拼接的url文件名
	if req.RecordsId == "" { //系统不会传RecordsId
		ossFileName = GetOssFileNameToManage(req)
	} else { //用户设备会传RecordsId
		ossFileName = GetOssFileName(req)
	}

	onlyFileName := fmt.Sprintf("%s%s", req.FileName, req.FileType) //单独的文件名

	// 这里做文件处理,我这里是分片上传至阿里云oss
	downloadURL, err = oss.OssClient.UploadFileByFragmentation(ctx, ossFileName, req.FileBytes, 3, onlyFileName)
	//err = uploadObject2OssV2(ctx, req.FileBytes, ossFileName)
	if err != nil {
		return
	}
	// 获取URL
	//downloadURL, err = oss.OssClient.SignURL(ctx, ossFileName)
	return
}

你可能感兴趣的:(golang,golang,json,开发语言)