This commit is contained in:
2025-07-04 23:41:19 +08:00
parent 7c2c32a31a
commit f0fd00d706
27 changed files with 1206 additions and 163 deletions

View File

@@ -3,10 +3,38 @@ package server
import (
"common/log"
"common/proto/gen/common"
"context"
"common/proto/gen/cs"
"common/proto/gen/grpc_pb"
"gateway/handler/ws_handler"
"sync"
)
func (s *Server) SendMessage(ctx context.Context, req *common.Empty) (*common.Empty, error) {
log.Infof("未实现函数")
return nil, nil
func (s *Server) ToClient(server grpc_pb.Gateway_ToClientServer) error {
wg := &sync.WaitGroup{}
wg.Add(1)
go func() {
defer wg.Done()
defer func() {
if err := recover(); err != nil {
log.Errorf("Action panic: %v", err)
}
}()
for {
if args, err := server.Recv(); err != nil {
return
} else {
if args.UID == -1 {
for _, client := range ws_handler.UserMgr.GetAll() {
client.WriteBytes(cs.MessageID(args.MessageID), args.Payload)
}
} else {
if client := ws_handler.UserMgr.GetByUID(int(args.UID)); client != nil {
client.WriteBytes(cs.MessageID(args.MessageID), args.Payload)
}
}
}
}
}()
wg.Wait()
return server.SendAndClose(&common.Empty{})
}

View File

@@ -4,6 +4,7 @@ import (
"common/discover/common"
"common/net/grpc/service"
"common/proto/gen/grpc_pb"
"gateway/handler/ws_handler"
"google.golang.org/grpc"
)
@@ -25,6 +26,7 @@ func NewServer(ttl int64) *Server {
}
func (s *Server) OnInit(serve *grpc.Server) {
ws_handler.GatewaySID = s.SID
grpc_pb.RegisterGatewayServer(serve, s)
}

View File

@@ -5,6 +5,7 @@ import (
"common/net/grpc/service"
"context"
"google.golang.org/grpc"
"google.golang.org/protobuf/proto"
)
var sceneServerM map[int64]map[SceneFun]grpc.ClientStream // map[sid]map[方法名]流连接
@@ -15,7 +16,11 @@ const (
FunAction SceneFun = iota
)
func FindSceneBySID(sid int64, fun SceneFun) grpc.ClientStream {
func init() {
sceneServerM = make(map[int64]map[SceneFun]grpc.ClientStream)
}
func FindSceneBySID(sid int64, fun SceneFun) (grpc.ClientStream, error) {
g := sceneServerM[sid]
if g == nil {
g = make(map[SceneFun]grpc.ClientStream)
@@ -26,7 +31,7 @@ func FindSceneBySID(sid int64, fun SceneFun) grpc.ClientStream {
sceneClient, err := service.SceneNewClient(sid)
if err != nil {
log.Errorf("cannot find sceneClient: %v", err)
return nil
return nil, err
}
var link grpc.ClientStream
switch fun {
@@ -35,10 +40,26 @@ func FindSceneBySID(sid int64, fun SceneFun) grpc.ClientStream {
}
if err != nil {
log.Errorf("FindSceneBySID %v err: %v, sid: %v", fun, err, sid)
return nil
return nil, err
}
g[fun] = link
sceneLink = link
}
return sceneLink
return sceneLink, nil
}
func SendMessageToScene(sid int64, fun SceneFun, msg proto.Message, re ...bool) error {
stream, err := FindSceneBySID(sid, fun)
if err != nil {
return err
}
if err = stream.SendMsg(msg); err != nil {
if re == nil || !re[0] {
_ = stream.CloseSend()
delete(sceneServerM[sid], fun)
return SendMessageToScene(sid, fun, msg, true)
}
return err
}
return nil
}

View File

@@ -3,14 +3,18 @@ package ws_handler
import (
"common/log"
"common/net/socket"
"common/proto/gen/cs"
"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
@@ -20,8 +24,10 @@ type Client struct {
cancel context.CancelFunc // 取消上下文
heartBeat time.Time // 最后一次心跳
UID int
SceneSID int64 // 场景服ID
UID int
SceneSID int64 // 场景服ID
InstanceID int
UniqueNo int64
}
func NewClient(uid int, conn socket.ISocketConn) *Client {
@@ -78,6 +84,39 @@ func (c *Client) OnEvent(event Event) {
}
}
func (c *Client) WriteMessage(id cs.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(&cs.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)
}
}
func (c *Client) WriteBytes(id cs.MessageID, data []byte) {
m, err := proto.Marshal(&cs.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 {

View File

@@ -2,25 +2,39 @@ package ws_handler
import (
"common/net/grpc/service"
"common/proto/gen/cs"
"common/proto/gen/grpc_pb"
"encoding/json"
"gateway/grpc_server/stream_client"
"google.golang.org/protobuf/proto"
"time"
)
func (c *Client) handle(event Event) {
switch e := event.(type) {
case *ClientEvent:
m, err := parseMsg(e.Msg)
if err != nil {
c.logger.Errorf("handle event json.Unmarshal err: %v", err)
msg := &cs.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", *m)
switch m.Type {
case "enter":
c.logger.Infof("收到客户端消息:%v", msg.ID)
switch msg.ID {
case cs.MessageID_MESSAGE_ID_ENTER_INSTANCE:
m := &cs.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 "action":
case cs.MessageID_MESSAGE_ID_ACTION:
m := &cs.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:
@@ -28,11 +42,7 @@ func (c *Client) handle(event Event) {
}
}
func (c *Client) onEnter(msg *tempMsg) {
//_ = c.conn.Write(wapMsg(&tempMsg{
// Type: "init",
// Data: fmt.Sprintf("[%v,%v]", utils.RandInt(1, 100), utils.RandInt(1, 100)),
//}))
func (c *Client) onEnter(msg *cs.C2S_EnterInstance) {
client, err := service.SceneNewClient()
if err != nil {
c.logger.Errorf("SceneNewClient err: %v", err)
@@ -40,31 +50,34 @@ func (c *Client) onEnter(msg *tempMsg) {
}
resp, err := client.Enter(c.ctx, &grpc_pb.EnterReq{
UID: int32(c.UID),
SID: 0,
InstanceID: 1,
GatewaySID: GatewaySID,
InstanceID: msg.InstanceID,
})
if err != nil {
c.logger.Errorf("enter err: %v", err)
return
}
c.SceneSID = resp.SID
c.SceneSID = resp.SceneSID
c.UniqueNo = resp.UniqueNo
c.InstanceID = int(msg.InstanceID)
c.WriteMessage(cs.MessageID_MESSAGE_ID_POSITION, &cs.S2C_Position{
Info: []*cs.PositionInfo{{
UID: int32(c.UID),
X: 1,
Y: 1,
}},
})
}
func (c *Client) onAction(msg *tempMsg) {
func (c *Client) onAction(msg *cs.C2S_Action) {
if c.SceneSID == 0 {
return
}
d := &tempAction{}
if err := json.Unmarshal([]byte(msg.Data), d); err != nil {
return
}
m := &tempActionMove{}
if err := json.Unmarshal([]byte(d.Data), m); err != nil {
return
}
stream := stream_client.FindSceneBySID(c.SceneSID, stream_client.FunAction)
if err := stream.SendMsg(&grpc_pb.ActionReq{
Action: int32(m.Move),
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

@@ -1,30 +0,0 @@
package ws_handler
import "encoding/json"
type tempMsg struct {
Type string `json:"type"`
Data string `json:"data"`
}
type tempAction struct {
Action int `json:"action"`
Data string `json:"data"`
}
type tempActionMove struct {
Move int `json:"move"`
}
func parseMsg(data []byte) (*tempMsg, error) {
m := &tempMsg{}
if err := json.Unmarshal(data, m); err != nil {
return nil, err
}
return m, nil
}
func wapMsg(m *tempMsg) []byte {
data, _ := json.Marshal(m)
return data
}

View File

@@ -30,6 +30,9 @@ func (g *GatewayWsServer) OnHandShake(conn socket.ISocketConn) {
if err != nil {
_ = conn.Close()
}
if oldClient := ws_handler.UserMgr.GetByUID(t); oldClient != nil {
oldClient.CloseClient()
}
client := ws_handler.NewClient(t, conn)
ws_handler.UserMgr.Add(t, client)
conn.SetParam("client", client)