feat 改名

This commit is contained in:
2025-12-15 11:29:27 +08:00
parent f511364984
commit 4983638c19
27 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,18 @@
package helper
type Pagination struct {
Page int `json:"page"` // 页
Size int `json:"size"` // 页大小
}
//func SetBaseQuery(page *Pagination, order string) func(db *gorm.DB) *gorm.DB {
// return func(db *gorm.DB) *gorm.DB {
// if page != nil {
// db = db.Offset((page.Page - 1) * page.Size).Limit(page.Size)
// }
// if len(order) > 0 {
// db = db.Order(order)
// }
// return db
// }
//}

View File

@@ -0,0 +1,31 @@
package render
var (
OK = NewCode(0, "成功")
Failed = NewCode(1, "失败")
ParamError = NewCode(1001, "参数错误")
NameEmpty = NewCode(1002, "名称不能为空")
NameDuplicate = NewCode(1003, "名称或编号不能重复")
ListEmpty = NewCode(1004, "列表不能为空")
RepeatCommit = NewCode(1005, "请勿重复提交")
)
type Code struct {
code int
message string
}
func NewCode(code int, message string) *Code {
return &Code{
code: code,
message: message,
}
}
func (c *Code) Code() int {
return c.code
}
func (c *Code) Message() string {
return c.message
}

View File

@@ -0,0 +1,39 @@
package render
import (
"github.com/gin-gonic/gin"
"net/http"
)
type RespJsonData struct {
Code int `json:"code"`
Msg string `json:"msg"`
Data interface{} `json:"data"`
}
func Json(c *gin.Context, code *Code, data interface{}) {
result := &RespJsonData{
Code: code.Code(),
Msg: code.Message(),
Data: data,
}
c.JSON(http.StatusOK, result)
}
func JsonByStatus(c *gin.Context, status int, code *Code, data interface{}) {
result := &RespJsonData{
Code: code.Code(),
Msg: code.Message(),
Data: data,
}
c.JSON(status, result)
}
func AbortJson(c *gin.Context, code *Code, data interface{}) {
result := &RespJsonData{
Code: code.Code(),
Msg: code.Message(),
Data: data,
}
c.AbortWithStatusJSON(http.StatusOK, result)
}

View File

@@ -0,0 +1,16 @@
package http_handler
import (
"common/utils"
"gateway/handler/http_handler/helper/render"
"github.com/gin-gonic/gin"
)
type UniqueIDResp struct {
ID string `json:"id"`
}
// GenSnowflake 生成雪花ID
func GenSnowflake(c *gin.Context) {
render.Json(c, render.OK, &UniqueIDResp{ID: utils.SnowflakeInstance().Generate().String()})
}

View File

@@ -0,0 +1,141 @@
package ws_handler
import (
"common/log"
"common/net/socket"
"common/proto/sc/sc_pb"
"context"
"fmt"
"go.uber.org/zap"
"google.golang.org/protobuf/proto"
"runtime/debug"
"sync"
"time"
)
var GatewaySID int64
type Client struct {
sync.WaitGroup
conn socket.ISocketConn // Socket
mailChan chan Event // 邮箱队列
logger *zap.SugaredLogger // 日志
ctx context.Context // 上下文
cancel context.CancelFunc // 取消上下文
heartBeat time.Time // 最后一次心跳
UID int
SceneSID int64 // 场景服ID
InstanceID int
UniqueNo int64
}
func NewClient(uid int, conn socket.ISocketConn) *Client {
client := &Client{
UID: uid,
conn: conn,
logger: log.GetLogger().Named(fmt.Sprintf("uid:%v", uid)),
heartBeat: time.Now(),
mailChan: make(chan Event, 1024),
}
client.ctx, client.cancel = context.WithCancel(context.Background())
client.Add(1)
go client.Loop()
return client
}
func (c *Client) Loop() {
defer func() {
if err := recover(); err != nil {
c.logger.Errorf("Client Loop err: %v", err)
debug.PrintStack()
}
}()
defer c.onClose()
t := time.NewTicker(20 * time.Second)
defer t.Stop()
for {
select {
case <-c.ctx.Done():
return
case evt, ok := <-c.mailChan:
if ok {
c.handle(evt)
}
case <-t.C:
_ = c.conn.Ping()
if time.Now().Sub(c.heartBeat) > 120*time.Second {
return
}
}
}
}
func (c *Client) OnEvent(event Event) {
defer func() {
if err := recover(); err != nil {
c.logger.Warnf(fmt.Sprintf("send event chan error: %v", err))
}
}()
select {
case c.mailChan <- event:
default:
c.logger.Warnf("Client mailChan full")
}
}
// WriteMessage 向客户端发送消息
func (c *Client) WriteMessage(id sc_pb.MessageID, data proto.Message) {
d, err := proto.Marshal(data)
if err != nil {
c.logger.Errorf("WriteMessage proto.Marshal err: %v", err)
return
}
m, err := proto.Marshal(&sc_pb.Message{
ID: id,
Payload: d,
})
if err != nil {
c.logger.Errorf("WriteMessage proto.Marshal err: %v", err)
return
}
if err = c.conn.Write(m); err != nil {
c.logger.Errorf("WriteMessage err: %v", err)
}
}
// WriteBytes 向客户端发送字节数据
func (c *Client) WriteBytes(id sc_pb.MessageID, data []byte) {
m, err := proto.Marshal(&sc_pb.Message{
ID: id,
Payload: data,
})
if err != nil {
c.logger.Errorf("WriteBytes proto.Marshal err: %v", err)
return
}
if err = c.conn.Write(m); err != nil {
c.logger.Errorf("WriteBytes err: %v", err)
}
}
// CloseClient 关闭客户端同步会等待onClose执行完成
func (c *Client) CloseClient() {
if c.cancel != nil {
c.cancel()
c.Wait()
}
}
func (c *Client) onClose() {
if c.conn != nil {
_ = c.conn.Close()
c.conn = nil
}
if c.mailChan != nil {
close(c.mailChan)
c.mailChan = nil
}
UserMgr.Delete(c.UID)
c.Done()
}

View File

@@ -0,0 +1,13 @@
package ws_handler
type Event interface {
}
type ClientEvent struct {
Event
Msg []byte
}
type PongEvent struct {
Event
}

View File

@@ -0,0 +1,84 @@
package ws_handler
import (
"common/net/grpc/service"
"common/proto/sc/sc_pb"
"common/proto/ss/grpc_pb"
"gateway/grpc_server/stream_client"
"google.golang.org/protobuf/proto"
"time"
)
func (c *Client) handle(event Event) {
switch e := event.(type) {
case *ClientEvent:
msg := &sc_pb.Message{}
if err := proto.Unmarshal(e.Msg, msg); err != nil {
c.logger.Errorf("handle event proto.Unmarshal err: %v", err)
c.cancel()
return
}
c.logger.Infof("收到客户端消息:%v", msg.ID)
switch msg.ID {
case sc_pb.MessageID_MESSAGE_ID_ENTER_INSTANCE:
m := &sc_pb.C2S_EnterInstance{}
if err := proto.Unmarshal(msg.Payload, m); err != nil {
c.logger.Errorf("handle event proto.Unmarshal err: %v", err)
c.cancel()
return
}
c.onEnter(m)
case sc_pb.MessageID_MESSAGE_ID_ACTION:
m := &sc_pb.C2S_Action{}
if err := proto.Unmarshal(msg.Payload, m); err != nil {
c.logger.Errorf("handle event proto.Unmarshal err: %v", err)
c.cancel()
return
}
c.onAction(m)
}
case *PongEvent:
c.heartBeat = time.Now()
}
}
func (c *Client) onEnter(msg *sc_pb.C2S_EnterInstance) {
client, err := service.SceneNewClient()
if err != nil {
c.logger.Errorf("SceneNewClient err: %v", err)
return
}
resp, err := client.Enter(c.ctx, &grpc_pb.EnterReq{
UID: int32(c.UID),
GatewaySID: GatewaySID,
InstanceID: msg.InstanceID,
})
if err != nil {
c.logger.Errorf("enter err: %v", err)
return
}
c.SceneSID = resp.SceneSID
c.UniqueNo = resp.UniqueNo
c.InstanceID = int(msg.InstanceID)
c.WriteMessage(sc_pb.MessageID_MESSAGE_ID_POSITION, &sc_pb.S2C_Position{
Info: []*sc_pb.PositionInfo{{
UID: int32(c.UID),
X: 1,
Y: 1,
}},
})
}
func (c *Client) onAction(msg *sc_pb.C2S_Action) {
if c.SceneSID == 0 {
return
}
if err := stream_client.SendMessageToScene(c.SceneSID, stream_client.FunAction, &grpc_pb.ActionReq{
UniqueNo: c.UniqueNo,
UID: int32(c.UID),
Action: int32(msg.Action),
Payload: msg.Payload,
}); err != nil {
c.logger.Errorf("send action err: %v", err)
}
}

View File

@@ -0,0 +1,42 @@
package ws_handler
import (
"sync"
)
var UserMgr *userManager
type userManager struct {
userMap map[int]*Client
sync.RWMutex
}
func init() {
UserMgr = &userManager{
userMap: make(map[int]*Client),
}
}
func (m *userManager) Add(uid int, client *Client) {
m.Lock()
defer m.Unlock()
m.userMap[uid] = client
}
func (m *userManager) Delete(uid int) {
m.Lock()
defer m.Unlock()
delete(m.userMap, uid)
}
func (m *userManager) GetAll() map[int]*Client {
m.RLock()
defer m.RUnlock()
return m.userMap
}
func (m *userManager) GetByUID(uid int) *Client {
m.RLock()
defer m.RUnlock()
return m.userMap[uid]
}