97 lines
2.4 KiB
Go
97 lines
2.4 KiB
Go
package logic
|
||
|
||
import (
|
||
"context"
|
||
"crypto/md5"
|
||
"encoding/hex"
|
||
"encoding/json"
|
||
"fmt"
|
||
"fusenapi/server/websocket/internal/config"
|
||
"github.com/zeromicro/go-zero/core/logx"
|
||
"net"
|
||
"time"
|
||
)
|
||
|
||
var (
|
||
//取消unity僵尸任务控制通道
|
||
cancelUnityCtlChan = make(chan cancelUnityCtlChanItem, 1000)
|
||
cancelRenderContextPanicMsg any = "cancel_render_context_panic_msg"
|
||
)
|
||
|
||
// 控制通道元素
|
||
type cancelUnityCtlChanItem struct {
|
||
Wid string `json:"wid"` //ws的唯一id
|
||
DeadlineTime int64 `json:"deadline_time"` //截断时间
|
||
Sign string `json:"sign"` //有效签名
|
||
}
|
||
|
||
// 取消渲染抛出的异常
|
||
func cancelRenderPanic() {
|
||
panic(cancelRenderContextPanicMsg)
|
||
}
|
||
|
||
// 判断是否是取消渲染的异常
|
||
func isCancelRenderPanic(err any) bool {
|
||
return err == cancelRenderContextPanicMsg
|
||
}
|
||
|
||
// 发送取消上下文消息给unity
|
||
func sendCancelRenderMsgToUnity(wid string, deadlineTime int64) {
|
||
data := cancelUnityCtlChanItem{
|
||
Wid: wid,
|
||
DeadlineTime: deadlineTime,
|
||
Sign: signMessage(wid, deadlineTime),
|
||
}
|
||
select {
|
||
case cancelUnityCtlChan <- data:
|
||
case <-time.After(time.Millisecond * 200):
|
||
logx.Error("sendCancelRenderMsgToUnity数据超时丢弃")
|
||
}
|
||
}
|
||
|
||
// 拨号udp
|
||
func DialUdp(ctx context.Context, config config.Config) error {
|
||
localAddr := &net.UDPAddr{IP: net.ParseIP(config.Unity.Udp.LocalAddr), Port: config.Unity.Udp.LocalPort}
|
||
remoteAddr := &net.UDPAddr{IP: net.ParseIP(config.Unity.Udp.RemoteAddr), Port: config.Unity.Udp.RemotePort}
|
||
conn, err := net.DialUDP("udp", localAddr, remoteAddr)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
go ConsumeCancelUnityChanMessage(ctx, conn)
|
||
return nil
|
||
}
|
||
|
||
// 签名消息
|
||
func signMessage(wid string, deadlineTime int64) string {
|
||
h := md5.New()
|
||
h.Write([]byte(fmt.Sprintf("%s_fusen_control_unity_%d", wid, deadlineTime)))
|
||
return hex.EncodeToString(h.Sum(nil))
|
||
}
|
||
|
||
// 消费数据
|
||
func ConsumeCancelUnityChanMessage(ctx context.Context, conn *net.UDPConn) {
|
||
defer func() {
|
||
if err := recover(); err != nil {
|
||
logx.Error("ConsumeCancelUnityChanMessage 异常:", err)
|
||
}
|
||
}()
|
||
go func() {
|
||
select {
|
||
case <-ctx.Done():
|
||
panic(any("ConsumeCancelUnityChanMessage ctx deadline"))
|
||
}
|
||
}()
|
||
defer conn.Close()
|
||
for {
|
||
select {
|
||
case data := <-cancelUnityCtlChan:
|
||
d, _ := json.Marshal(data)
|
||
_, err := conn.Write(d)
|
||
if err != nil {
|
||
logx.Error("发送udp包通知Unity失败:", err)
|
||
continue
|
||
}
|
||
}
|
||
}
|
||
}
|