2023-07-26 06:35:29 +00:00
package logic
2023-08-23 07:08:45 +00:00
//处理websocket云渲染任务数据
2023-07-26 06:35:29 +00:00
import (
2023-08-16 04:33:01 +00:00
"bytes"
2023-07-26 06:35:29 +00:00
"encoding/json"
2023-08-09 08:06:40 +00:00
"errors"
2023-08-21 08:19:30 +00:00
"fmt"
2023-07-27 09:33:50 +00:00
"fusenapi/constants"
2023-08-24 10:02:00 +00:00
"fusenapi/model/gmodel"
2023-08-16 04:16:23 +00:00
"fusenapi/service/repositories"
2023-08-16 04:33:01 +00:00
"fusenapi/utils/curl"
2023-08-07 02:48:14 +00:00
"fusenapi/utils/hash"
2023-08-24 06:24:04 +00:00
"fusenapi/utils/websocket_data"
2023-07-26 06:35:29 +00:00
"github.com/zeromicro/go-zero/core/logx"
2023-08-09 08:06:40 +00:00
"gorm.io/gorm"
2023-08-16 04:16:23 +00:00
"strconv"
2023-08-16 04:33:01 +00:00
"time"
2023-07-26 06:35:29 +00:00
)
2023-07-26 09:06:53 +00:00
// 云渲染属性
2023-08-24 04:04:58 +00:00
type extendRenderProperty struct {
2023-08-21 08:19:30 +00:00
renderImageTask map [ string ] * renderTask //需要渲染的图片任务 key是taskId val 是renderId
2023-08-23 04:29:02 +00:00
renderImageTaskCtlChan chan renderImageControlChanItem //渲染任务新增/回调结果移除任务/更新渲染耗时属性的控制通道( 由于任务map无法读写并发)
renderChan chan [ ] byte //渲染消息入口的缓冲队列
2023-08-21 08:19:30 +00:00
}
2023-07-26 09:06:53 +00:00
// 渲染任务新增移除的控制通道的数据
type renderImageControlChanItem struct {
2023-08-28 10:16:19 +00:00
option int // 0删除 1添加 2修改耗时属性
taskId string //map的key(必须传)
2023-08-28 06:44:46 +00:00
renderId string // map的val(增加任务时候传)
renderNotifyImageUrl string //渲染回调数据(删除任务时候传)
taskProperty renderTask //渲染任务的属性
2023-07-27 09:41:36 +00:00
}
2023-08-23 04:29:02 +00:00
// 渲染任务属性
type renderTask struct {
2023-08-28 11:00:08 +00:00
renderId string //渲染id(新增任务传)
2023-08-28 06:44:46 +00:00
combineTakesTime int64 //合刀版图耗时
uploadCombineImageTakesTime int64 //上传刀版图耗时
unityRenderBeginTime int64 //发送给unity时间
unityRenderEndTime int64 //unity回调结果时间
uploadUnityRenderImageTakesTime int64 //上传unity渲染结果图时间
2023-08-23 04:29:02 +00:00
}
2023-08-28 07:50:18 +00:00
// 发送到渲染缓冲队列
2023-08-16 08:20:16 +00:00
func ( w * wsConnectItem ) sendToRenderChan ( data [ ] byte ) {
select {
case <- w . closeChan : //已经关闭
return
2023-08-28 07:50:18 +00:00
case w . extendRenderProperty . renderChan <- data : //发入到缓冲队列
2023-08-16 08:20:16 +00:00
return
2023-08-28 07:50:18 +00:00
case <- time . After ( time . Second * 3 ) : //三秒没进入缓冲队列就丢弃
2023-08-16 08:20:16 +00:00
return
}
}
2023-08-30 03:13:10 +00:00
// 消费渲染缓冲队列数据
func ( w * wsConnectItem ) consumeRenderImageData ( ) {
2023-08-29 02:21:11 +00:00
defer func ( ) {
if err := recover ( ) ; err != nil {
logx . Error ( "func renderImage err:" , err )
}
} ( )
2023-08-16 08:20:16 +00:00
for {
select {
case <- w . closeChan : //已关闭
return
2023-08-24 04:04:58 +00:00
case data := <- w . extendRenderProperty . renderChan :
2023-08-16 08:20:16 +00:00
w . consumeRenderCache ( data )
}
}
}
// 消费渲染缓冲数据
func ( w * wsConnectItem ) consumeRenderCache ( data [ ] byte ) {
2023-08-16 09:04:45 +00:00
logx . Info ( "消费渲染数据:" , string ( data ) )
2023-08-24 06:24:04 +00:00
var renderImageData websocket_data . RenderImageReqMsg
2023-07-27 09:41:36 +00:00
if err := json . Unmarshal ( data , & renderImageData ) ; err != nil {
2023-08-24 09:23:41 +00:00
w . incomeDataFormatErrResponse ( "invalid format of render data:" + string ( data ) )
2023-07-27 09:41:36 +00:00
logx . Error ( "invalid format of websocket render image message" , err )
return
}
2023-08-09 10:09:16 +00:00
//获取上传最近的logo
2023-08-16 06:09:03 +00:00
userMaterial , err := w . logic . svcCtx . AllModels . FsUserMaterial . FindLatestOne ( w . logic . ctx , w . userId , w . guestId )
2023-08-09 10:09:16 +00:00
if err != nil {
if ! errors . Is ( err , gorm . ErrRecordNotFound ) {
2023-08-28 10:37:58 +00:00
w . renderErrResponse ( renderImageData . RenderId , renderImageData . RenderData . TemplateTag , "" , "failed to get user logo" , w . userId , w . guestId , 0 , 0 , 0 , 0 )
2023-08-09 10:09:16 +00:00
logx . Error ( "failed to get user logo" )
return
}
2023-08-15 07:09:53 +00:00
//使用默认logo(id=0)
2023-08-16 06:09:03 +00:00
userMaterialDefault , err := w . logic . svcCtx . AllModels . FsUserMaterial . FindOneById ( w . logic . ctx , 0 )
2023-08-15 07:09:53 +00:00
if err != nil {
if errors . Is ( err , gorm . ErrRecordNotFound ) {
2023-08-28 10:37:58 +00:00
w . renderErrResponse ( renderImageData . RenderId , renderImageData . RenderData . TemplateTag , "" , "default logo is not exists" , w . userId , w . guestId , 0 , 0 , 0 , 0 )
2023-08-15 07:09:53 +00:00
return
}
2023-08-28 10:37:58 +00:00
w . renderErrResponse ( renderImageData . RenderId , renderImageData . RenderData . TemplateTag , "" , "failed to get default logo" , w . userId , w . guestId , 0 , 0 , 0 , 0 )
2023-08-23 03:24:33 +00:00
logx . Error ( "default logo is not exists" )
2023-08-15 07:09:53 +00:00
return
}
renderImageData . RenderData . Logo = * userMaterialDefault . ResourceUrl
2023-08-09 10:09:16 +00:00
} else {
renderImageData . RenderData . Logo = * userMaterial . ResourceUrl
}
2023-08-09 04:28:06 +00:00
//用户id赋值
2023-08-08 04:22:15 +00:00
renderImageData . RenderData . UserId = w . userId
2023-08-09 04:28:06 +00:00
renderImageData . RenderData . GuestId = w . guestId
2023-08-29 06:35:04 +00:00
var productSize * gmodel . FsProductSize
//指定尺寸
2023-08-29 09:48:52 +00:00
if renderImageData . RenderData . ProductSizeId > 0 {
productSize , err = w . logic . svcCtx . AllModels . FsProductSize . FindOneByIdProductId ( w . logic . ctx , renderImageData . RenderData . ProductSizeId , renderImageData . RenderData . ProductId )
2023-08-29 06:35:04 +00:00
} else { //获取产品第一个尺寸
productSize , err = w . logic . svcCtx . AllModels . FsProductSize . GetProductFirstSize ( w . logic . ctx , renderImageData . RenderData . ProductId )
}
2023-08-24 10:02:00 +00:00
if err != nil {
if errors . Is ( err , gorm . ErrRecordNotFound ) {
2023-08-29 09:48:52 +00:00
w . renderErrResponse ( renderImageData . RenderId , renderImageData . RenderData . TemplateTag , "" , "product first size is not exists" , w . userId , w . guestId , 0 , 0 , renderImageData . RenderData . ProductSizeId , 0 )
2023-08-29 06:35:04 +00:00
logx . Error ( "product size is not found" )
2023-08-24 10:02:00 +00:00
return
}
2023-08-29 09:48:52 +00:00
w . renderErrResponse ( renderImageData . RenderId , renderImageData . RenderData . TemplateTag , "" , "failed to get product first size" , w . userId , w . guestId , 0 , 0 , renderImageData . RenderData . ProductSizeId , 0 )
2023-08-29 06:35:04 +00:00
logx . Error ( "failed to get product size:" , err )
2023-08-24 10:02:00 +00:00
return
}
//获取模型(只是获取id)
2023-08-29 06:35:04 +00:00
model3dInfo , err := w . logic . svcCtx . AllModels . FsProductModel3d . GetOneBySizeIdTag ( w . logic . ctx , productSize . Id , constants . TAG_MODEL , "id" )
2023-08-24 10:02:00 +00:00
if err != nil {
if errors . Is ( err , gorm . ErrRecordNotFound ) {
2023-08-29 06:35:04 +00:00
w . renderErrResponse ( renderImageData . RenderId , renderImageData . RenderData . TemplateTag , "" , "product model is not exists" , w . userId , w . guestId , 0 , 0 , productSize . Id , 0 )
2023-08-24 10:02:00 +00:00
logx . Error ( "product model is not found" )
return
}
2023-08-29 06:35:04 +00:00
w . renderErrResponse ( renderImageData . RenderId , renderImageData . RenderData . TemplateTag , "" , "failed to get product model" , w . userId , w . guestId , 0 , 0 , productSize . Id , 0 )
2023-08-24 10:02:00 +00:00
logx . Error ( "failed to get product model:" , err )
return
}
//获取模板
2023-08-28 10:37:58 +00:00
productTemplate , err := w . logic . svcCtx . AllModels . FsProductTemplateV2 . FindFirstOneCloudRenderByProductIdModelIdTemplateTag ( w . logic . ctx , renderImageData . RenderData . ProductId , model3dInfo . Id , renderImageData . RenderData . TemplateTag )
2023-08-24 10:02:00 +00:00
if err != nil {
if errors . Is ( err , gorm . ErrRecordNotFound ) {
2023-08-29 06:35:04 +00:00
w . renderErrResponse ( renderImageData . RenderId , renderImageData . RenderData . TemplateTag , "" , "product template is not exists" , w . userId , w . guestId , 0 , model3dInfo . Id , productSize . Id , 0 )
2023-08-24 10:02:00 +00:00
logx . Error ( "template info is not found" )
return
}
2023-08-29 06:35:04 +00:00
w . renderErrResponse ( renderImageData . RenderId , renderImageData . RenderData . TemplateTag , "" , "failed to get product template" , w . userId , w . guestId , 0 , model3dInfo . Id , productSize . Id , 0 )
2023-08-24 10:02:00 +00:00
logx . Error ( "failed to get template info:" , err )
return
}
//获取渲染设置信息
2023-08-29 02:31:25 +00:00
element , err := w . logic . svcCtx . AllModels . FsProductTemplateElement . FindOneByModelId ( w . logic . ctx , * productTemplate . ElementModelId )
2023-08-24 10:02:00 +00:00
if err != nil {
if errors . Is ( err , gorm . ErrRecordNotFound ) {
2023-08-29 06:35:04 +00:00
w . renderErrResponse ( renderImageData . RenderId , renderImageData . RenderData . TemplateTag , "" , "render element is not exists" , w . userId , w . guestId , productTemplate . Id , model3dInfo . Id , productSize . Id , * productTemplate . ElementModelId )
2023-08-29 02:21:11 +00:00
logx . Error ( "element info is not found,element_model_id = " , 0 )
2023-08-24 10:02:00 +00:00
return
}
2023-08-29 06:35:04 +00:00
w . renderErrResponse ( renderImageData . RenderId , renderImageData . RenderData . TemplateTag , "" , "failed to get render element" , w . userId , w . guestId , productTemplate . Id , model3dInfo . Id , productSize . Id , * productTemplate . ElementModelId )
2023-08-28 10:37:58 +00:00
logx . Error ( "failed to get element ," , err )
2023-08-24 10:02:00 +00:00
return
}
2023-08-28 10:16:19 +00:00
//获取刀版图
combineReq := repositories . LogoCombineReq {
UserId : renderImageData . RenderData . UserId ,
GuestId : renderImageData . RenderData . GuestId ,
TemplateId : productTemplate . Id ,
TemplateTag : renderImageData . RenderData . TemplateTag ,
Website : renderImageData . RenderData . Website ,
Slogan : renderImageData . RenderData . Slogan ,
Address : renderImageData . RenderData . Address ,
Phone : renderImageData . RenderData . Phone ,
2023-08-29 09:09:00 +00:00
Qrcode : renderImageData . RenderData . Qrcode ,
2023-08-29 09:10:58 +00:00
LogoUrl : renderImageData . RenderData . Logo ,
2023-08-28 10:16:19 +00:00
}
res , err := w . logic . svcCtx . Repositories . ImageHandle . LogoCombine ( w . logic . ctx , & combineReq )
if err != nil {
2023-08-29 06:35:04 +00:00
w . renderErrResponse ( renderImageData . RenderId , renderImageData . RenderData . TemplateTag , "" , "failed to combine image:" + err . Error ( ) , w . userId , w . guestId , productTemplate . Id , model3dInfo . Id , productSize . Id , * productTemplate . ElementModelId )
2023-08-28 10:16:19 +00:00
logx . Error ( "合成刀版图失败,合成请求数据:" , combineReq , "错误信息:" , err )
return
}
combineImage := "" //刀版图
if res != nil && res . ResourceUrl != nil {
combineImage = * res . ResourceUrl
} else {
2023-08-29 06:35:04 +00:00
w . renderErrResponse ( renderImageData . RenderId , renderImageData . RenderData . TemplateTag , "" , "combine image is empty" , w . userId , w . guestId , productTemplate . Id , model3dInfo . Id , productSize . Id , * productTemplate . ElementModelId )
2023-08-28 10:16:19 +00:00
logx . Error ( "合成刀版图失败,合成的刀版图是空指针:" , err )
return
}
2023-08-29 07:13:25 +00:00
//发送合图结果消息
w . sendToOutChan ( w . respondDataFormat ( constants . WEBSOCKET_COMBINE_IMAGE , websocket_data . CombineImageRspMsg {
RenderId : renderImageData . RenderId ,
CombineImage : combineImage ,
2023-08-29 08:24:59 +00:00
CombineProcessTime : websocket_data . CombineProcessTime {
CombineTakesTime : fmt . Sprintf ( "%dms" , res . DiffTimeLogoCombine ) ,
UploadCombineImageTakesTime : fmt . Sprintf ( "%dms" , res . DiffTimeUploadFile ) ,
} ,
2023-08-29 07:13:25 +00:00
} ) )
2023-08-29 09:40:09 +00:00
//如果指定指定只返回刀版图
if renderImageData . OnlyReturnCombineImage {
2023-08-29 07:18:50 +00:00
logx . Info ( "云渲染传入size id则不走unity云渲染,只返回刀版图, render_id:" , renderImageData . RenderId )
2023-08-29 07:04:11 +00:00
return
}
2023-08-24 10:02:00 +00:00
//获取唯一id
taskId := w . genRenderTaskId ( renderImageData , model3dInfo , productTemplate , element )
2023-08-09 08:06:40 +00:00
//查询有没有缓存的资源,有就返回######################
2023-08-16 06:09:03 +00:00
resource , err := w . logic . svcCtx . AllModels . FsResource . FindOneById ( w . logic . ctx , taskId )
2023-08-09 08:06:40 +00:00
if err != nil {
if ! errors . Is ( err , gorm . ErrRecordNotFound ) {
2023-08-29 06:35:04 +00:00
w . renderErrResponse ( renderImageData . RenderId , renderImageData . RenderData . TemplateTag , taskId , "failed to get render cache" , w . userId , w . guestId , productTemplate . Id , model3dInfo . Id , productSize . Id , * productTemplate . ElementModelId )
2023-08-09 08:06:40 +00:00
logx . Error ( "failed to find render resource:" , err )
return
}
} else {
//返回给客户端
2023-08-24 06:24:04 +00:00
b := w . respondDataFormat ( constants . WEBSOCKET_RENDER_IMAGE , websocket_data . RenderImageRspMsg {
2023-08-29 07:13:25 +00:00
RenderId : renderImageData . RenderId ,
Image : * resource . ResourceUrl ,
2023-08-25 04:02:07 +00:00
RenderProcessTime : websocket_data . RenderProcessTime {
CombineTakesTime : "cache" ,
UnityRenderTakesTime : "cache" ,
UploadCombineImageTakesTime : "cache" ,
UploadUnityRenderImageTakesTime : "cache" ,
} ,
2023-08-09 08:06:40 +00:00
} )
//发送数据到out chan
w . sendToOutChan ( b )
return
}
//###########################################
//把需要渲染的图片任务加进去
2023-08-21 05:19:12 +00:00
w . createRenderTask ( renderImageControlChanItem {
2023-08-28 11:00:08 +00:00
option : 1 , //0删除 1添加 2修改耗时属性
taskId : taskId ,
renderId : renderImageData . RenderId ,
2023-08-29 02:56:06 +00:00
} )
2023-08-29 03:34:02 +00:00
//记录刀版图合成消耗时间跟上传刀版图时间以及刀版图
2023-08-29 02:56:06 +00:00
w . modifyRenderTaskProperty ( renderImageControlChanItem {
option : 2 ,
taskId : taskId ,
2023-08-28 11:00:08 +00:00
taskProperty : renderTask {
2023-08-29 03:34:02 +00:00
combineTakesTime : res . DiffTimeLogoCombine ,
uploadCombineImageTakesTime : res . DiffTimeUploadFile ,
2023-08-28 11:00:08 +00:00
} ,
2023-08-21 05:19:12 +00:00
} )
2023-08-16 04:16:23 +00:00
//组装数据
2023-08-29 06:35:04 +00:00
if err = w . assembleRenderData ( taskId , combineImage , renderImageData , productTemplate , model3dInfo , element , productSize ) ; err != nil {
2023-08-16 08:20:16 +00:00
logx . Error ( "组装数据失败:" , err )
2023-08-07 02:48:14 +00:00
return
}
2023-08-16 04:16:23 +00:00
}
2023-08-24 10:02:00 +00:00
// 组装数据发送给unity
2023-08-29 06:35:04 +00:00
func ( w * wsConnectItem ) assembleRenderData ( taskId string , combineImage string , info websocket_data . RenderImageReqMsg , productTemplate * gmodel . FsProductTemplateV2 , model3dInfo * gmodel . FsProductModel3d , element * gmodel . FsProductTemplateElement , productSize * gmodel . FsProductSize ) ( err error ) {
2023-08-16 04:16:23 +00:00
//组装数据
refletion := - 1
if element . Refletion != nil && * element . Refletion != "" {
refletion , err = strconv . Atoi ( * element . Refletion )
2023-08-17 06:48:27 +00:00
if err != nil {
logx . Error ( "err refletion:set default -1" )
2023-08-29 06:35:04 +00:00
w . renderErrResponse ( info . RenderId , info . RenderData . TemplateTag , taskId , "parse element.Refletion from string to number err" , w . userId , w . guestId , productTemplate . Id , model3dInfo . Id , productSize . Id , * productTemplate . ElementModelId )
2023-08-24 09:23:41 +00:00
return err
2023-08-17 06:48:27 +00:00
}
2023-08-16 04:16:23 +00:00
}
//组装data数据
var mode map [ string ] interface { }
if element . Mode != nil && * element . Mode != "" {
if err = json . Unmarshal ( [ ] byte ( * element . Mode ) , & mode ) ; err != nil {
logx . Error ( "faile to parse element mode json:" , err )
2023-08-29 06:35:04 +00:00
w . renderErrResponse ( info . RenderId , info . RenderData . TemplateTag , taskId , "parse element.Mode err" , w . userId , w . guestId , productTemplate . Id , model3dInfo . Id , productSize . Id , * productTemplate . ElementModelId )
2023-08-16 08:20:16 +00:00
return err
2023-08-16 04:16:23 +00:00
}
}
tempData := make ( [ ] map [ string ] interface { } , 0 , 3 )
if element . Base != nil && * element . Base != "" {
tempData = append ( tempData , map [ string ] interface { } {
"name" : "model" ,
"data" : "0," + combineImage + "," + * element . Base ,
"type" : "other" ,
"layer" : "0" ,
"is_update" : 1 ,
"mode" : mode [ "model" ] ,
} )
}
if element . Shadow != nil && * element . Shadow != "" {
tempData = append ( tempData , map [ string ] interface { } {
"name" : "shadow" ,
"data" : * element . Shadow ,
"type" : "other" ,
"layer" : "0" ,
"is_update" : 0 ,
"mode" : mode [ "shadow" ] ,
} )
}
if element . ModelP != nil && * element . ModelP != "" {
tempData = append ( tempData , map [ string ] interface { } {
"name" : "model_P" ,
"data" : "0," + * element . ModelP ,
"type" : "other" ,
"layer" : "0" ,
"is_update" : 0 ,
"mode" : mode [ "model_P" ] ,
} )
}
result := [ ] interface { } {
map [ string ] interface { } {
"light" : * element . Light ,
"refletion" : refletion ,
"scale" : * element . Scale ,
"sku_id" : info . RenderData . ProductId ,
"tid" : * element . Title ,
"rotation" : * element . Rotation ,
"filePath" : "" , //todo 文件路径,针对千人千面
"data" : tempData ,
} ,
}
sendData := map [ string ] interface { } {
"id" : taskId ,
"order_id" : 0 ,
"user_id" : info . RenderData . UserId ,
"guest_id" : info . RenderData . GuestId ,
"sku_ids" : [ ] int64 { info . RenderData . ProductId } ,
"tids" : [ ] string { * element . Title } ,
"data" : result ,
"is_thousand_face" : 0 ,
"folder" : "" , //todo 千人千面需要使用
}
2023-08-16 06:09:03 +00:00
//请求unity接口
2023-08-17 08:07:27 +00:00
url := w . logic . svcCtx . Config . Unity . Host + "/api/render/queue/push"
2023-08-16 04:33:01 +00:00
header := make ( map [ string ] string )
header [ "content-type" ] = "application/json"
postData := map [ string ] interface { } {
"group" : "unity3d" ,
"source" : "home page" ,
"priority" : 1 ,
2023-08-25 03:06:32 +00:00
"create_at" : time . Now ( ) . UTC ( ) ,
2023-08-16 04:33:01 +00:00
"render_data" : sendData ,
}
2023-08-21 06:46:39 +00:00
postDataBytes , _ := json . Marshal ( postData )
2023-08-25 03:06:32 +00:00
unityRenderBeginTime := time . Now ( ) . UTC ( ) . UnixMilli ( )
2023-08-21 06:46:39 +00:00
_ , err = curl . ApiCall ( url , "POST" , header , bytes . NewReader ( postDataBytes ) , time . Second * 10 )
2023-08-16 04:33:01 +00:00
if err != nil {
2023-08-29 06:35:04 +00:00
w . renderErrResponse ( info . RenderId , info . RenderData . TemplateTag , taskId , "request unity api err" , w . userId , w . guestId , productTemplate . Id , model3dInfo . Id , productSize . Id , * productTemplate . ElementModelId )
2023-08-16 04:33:01 +00:00
logx . Error ( "failed to send data to unity" )
2023-08-16 08:20:16 +00:00
return err
2023-08-16 04:33:01 +00:00
}
2023-08-21 08:19:30 +00:00
//记录发送到unity时间
2023-08-29 02:56:06 +00:00
w . modifyRenderTaskProperty ( renderImageControlChanItem {
2023-08-28 06:44:46 +00:00
option : 2 ,
taskId : taskId ,
taskProperty : renderTask {
unityRenderBeginTime : unityRenderBeginTime ,
2023-08-21 08:19:30 +00:00
} ,
} )
2023-08-21 06:46:39 +00:00
logx . Info ( "发送到unity成功,刀版图:" , combineImage , " 请求unity的数据:" , string ( postDataBytes ) )
2023-08-16 08:20:16 +00:00
return nil
2023-08-07 02:48:14 +00:00
}
2023-08-21 05:19:12 +00:00
// 增加渲染任务
func ( w * wsConnectItem ) createRenderTask ( data renderImageControlChanItem ) {
//强制设为增加
2023-08-28 06:44:46 +00:00
data . option = 1
2023-08-21 05:19:12 +00:00
select {
case <- w . closeChan : //关闭
return
2023-08-24 04:04:58 +00:00
case w . extendRenderProperty . renderImageTaskCtlChan <- data :
2023-08-21 05:19:12 +00:00
return
case <- time . After ( time . Second * 3 ) :
return
}
}
// 渲染回调处理并删除渲染任务
func ( w * wsConnectItem ) deleteRenderTask ( data renderImageControlChanItem ) {
//强制设为删除
2023-08-28 06:44:46 +00:00
data . option = 0
2023-08-21 05:19:12 +00:00
select {
case <- w . closeChan : //关闭
return
2023-08-24 04:04:58 +00:00
case w . extendRenderProperty . renderImageTaskCtlChan <- data :
2023-08-21 05:19:12 +00:00
return
case <- time . After ( time . Second * 3 ) :
return
}
}
2023-08-29 02:56:06 +00:00
// 修改任务属性(只有耗时属性可以更新)
func ( w * wsConnectItem ) modifyRenderTaskProperty ( data renderImageControlChanItem ) {
2023-08-28 06:44:46 +00:00
if data . taskId == "" {
2023-08-22 10:22:27 +00:00
logx . Error ( "设置耗时属性需要的task_id不能为空" )
return
}
2023-08-21 08:19:30 +00:00
//强制设为修改耗时属性
2023-08-28 06:44:46 +00:00
data . option = 2
2023-08-21 08:19:30 +00:00
select {
case <- w . closeChan : //关闭
return
2023-08-24 04:04:58 +00:00
case w . extendRenderProperty . renderImageTaskCtlChan <- data :
2023-08-21 08:19:30 +00:00
return
case <- time . After ( time . Second * 3 ) :
return
}
}
2023-08-29 10:22:15 +00:00
// 组装渲染任务id
func ( w * wsConnectItem ) genRenderTaskId ( renderImageData websocket_data . RenderImageReqMsg , model3dInfo * gmodel . FsProductModel3d , productTemplate * gmodel . FsProductTemplateV2 , element * gmodel . FsProductTemplateElement ) string {
//生成任务id(需要把user_id,guest_id设为0)
incomeHashParam := renderImageData . RenderData
incomeHashParam . UserId = 0 //设为0(渲染跟用户id无关)
incomeHashParam . GuestId = 0 //设为0(渲染跟用户id无关)
incomeHashBytes , _ := json . Marshal ( incomeHashParam )
modelHashStr := ""
templateHashStr := ""
if model3dInfo . ModelInfo != nil {
modelHashStr = * model3dInfo . ModelInfo
}
if productTemplate . TemplateInfo != nil {
templateHashStr = * productTemplate . TemplateInfo
}
elementHashBytes , _ := json . Marshal ( element )
hashMap := map [ string ] interface { } {
"income_param" : incomeHashBytes ,
"model_info" : modelHashStr ,
"template_info" : templateHashStr ,
"material_image" : * productTemplate . MaterialImg ,
"render_element" : elementHashBytes ,
}
return hash . JsonHashKey ( hashMap )
}
2023-08-22 10:24:24 +00:00
// 处理渲染任务的增加/删除/修改耗时属性( 任务map不能读写并发, 所以放在chan里面串行执行)
2023-08-07 02:48:14 +00:00
func ( w * wsConnectItem ) operationRenderTask ( ) {
2023-08-22 10:37:49 +00:00
defer func ( ) {
if err := recover ( ) ; err != nil {
logx . Error ( "operation render task panic:" , err )
}
} ( )
2023-08-07 02:48:14 +00:00
for {
2023-07-27 07:46:07 +00:00
select {
2023-08-07 02:48:14 +00:00
case <- w . closeChan :
2023-07-27 07:46:07 +00:00
return
2023-08-24 04:04:58 +00:00
case data := <- w . extendRenderProperty . renderImageTaskCtlChan :
2023-08-28 06:44:46 +00:00
switch data . option {
2023-08-21 05:19:12 +00:00
case 0 : //渲染结果回调,删除任务
//存在任务,则发送渲染结果给前端
2023-08-28 06:44:46 +00:00
if taskData , ok := w . extendRenderProperty . renderImageTask [ data . taskId ] ; ok {
2023-08-25 03:06:32 +00:00
CombineTakesTime := "0ms"
UnityRenderTakesTime := "0ms"
uploadCombineImageTakesTime := "0ms"
uploadUnityRenderImageTakesTime := "0ms"
//合图时间
2023-08-28 06:44:46 +00:00
if taskData . combineTakesTime > 0 {
CombineTakesTime = fmt . Sprintf ( "%dms" , taskData . combineTakesTime )
2023-08-25 03:06:32 +00:00
}
//上传刀版图时间
2023-08-28 06:44:46 +00:00
if taskData . uploadCombineImageTakesTime > 0 {
uploadCombineImageTakesTime = fmt . Sprintf ( "%dms" , taskData . uploadCombineImageTakesTime )
2023-08-21 08:19:30 +00:00
}
2023-08-25 03:06:32 +00:00
//unity渲染时间
2023-08-28 06:44:46 +00:00
if taskData . unityRenderBeginTime > 0 && taskData . unityRenderEndTime > 0 {
UnityRenderTakesTime = fmt . Sprintf ( "%dms" , taskData . unityRenderEndTime - taskData . unityRenderBeginTime )
2023-08-25 03:06:32 +00:00
}
//上传unity渲染图耗时
2023-08-28 06:44:46 +00:00
if taskData . uploadUnityRenderImageTakesTime > 0 {
uploadUnityRenderImageTakesTime = fmt . Sprintf ( "%dms" , taskData . uploadUnityRenderImageTakesTime )
2023-08-21 08:19:30 +00:00
}
//发送到出口
2023-08-24 06:24:04 +00:00
w . sendToOutChan ( w . respondDataFormat ( constants . WEBSOCKET_RENDER_IMAGE , websocket_data . RenderImageRspMsg {
2023-08-29 07:13:25 +00:00
RenderId : taskData . renderId ,
Image : data . renderNotifyImageUrl ,
2023-08-25 04:01:01 +00:00
RenderProcessTime : websocket_data . RenderProcessTime {
CombineTakesTime : CombineTakesTime ,
UnityRenderTakesTime : UnityRenderTakesTime ,
UploadCombineImageTakesTime : uploadCombineImageTakesTime ,
UploadUnityRenderImageTakesTime : uploadUnityRenderImageTakesTime ,
} ,
2023-08-21 05:19:12 +00:00
} ) )
}
2023-08-22 08:07:05 +00:00
//删除任务
2023-08-28 06:44:46 +00:00
delete ( w . extendRenderProperty . renderImageTask , data . taskId )
2023-08-07 02:48:14 +00:00
case 1 : //新增任务
2023-08-28 06:44:46 +00:00
w . extendRenderProperty . renderImageTask [ data . taskId ] = & renderTask {
2023-08-29 02:56:06 +00:00
renderId : data . renderId ,
2023-08-21 08:19:30 +00:00
}
2023-08-28 11:00:08 +00:00
2023-08-29 03:34:02 +00:00
case 2 : //修改任务属性
2023-08-28 06:44:46 +00:00
if taskData , ok := w . extendRenderProperty . renderImageTask [ data . taskId ] ; ok {
2023-08-25 03:06:32 +00:00
//合图耗时
2023-08-28 06:44:46 +00:00
if data . taskProperty . combineTakesTime != 0 {
taskData . combineTakesTime = data . taskProperty . combineTakesTime
2023-08-25 03:06:32 +00:00
}
//上传合图耗时
2023-08-28 06:44:46 +00:00
if data . taskProperty . uploadCombineImageTakesTime != 0 {
taskData . uploadCombineImageTakesTime = data . taskProperty . uploadCombineImageTakesTime
2023-08-21 08:19:30 +00:00
}
2023-08-25 03:06:32 +00:00
//上传渲染结果图耗时
2023-08-28 06:44:46 +00:00
if data . taskProperty . uploadUnityRenderImageTakesTime != 0 {
taskData . uploadUnityRenderImageTakesTime = data . taskProperty . uploadUnityRenderImageTakesTime
2023-08-21 08:19:30 +00:00
}
2023-08-25 03:06:32 +00:00
//发送unity时间
2023-08-28 06:44:46 +00:00
if data . taskProperty . unityRenderBeginTime != 0 {
taskData . unityRenderBeginTime = data . taskProperty . unityRenderBeginTime
2023-08-21 08:19:30 +00:00
}
2023-08-25 03:06:32 +00:00
//收到unity返回的时间
2023-08-28 06:44:46 +00:00
if data . taskProperty . unityRenderEndTime != 0 {
taskData . unityRenderEndTime = data . taskProperty . unityRenderEndTime
2023-08-21 08:19:30 +00:00
}
}
2023-07-28 09:15:37 +00:00
}
2023-07-26 07:01:59 +00:00
}
2023-07-26 06:35:29 +00:00
}
}