118 lines
3.6 KiB
Go
118 lines
3.6 KiB
Go
package gameService
|
||
|
||
import (
|
||
"fmt"
|
||
"game/common/config"
|
||
"game/common/constant"
|
||
"game/common/proto/pb"
|
||
"game/common/userBindService"
|
||
"game/common/utils"
|
||
"github.com/fox/fox/db"
|
||
"github.com/fox/fox/etcd"
|
||
"github.com/fox/fox/ipb"
|
||
"github.com/fox/fox/log"
|
||
"github.com/fox/fox/processor"
|
||
"github.com/fox/fox/service"
|
||
"github.com/go-redis/redis/v8"
|
||
"github.com/golang/protobuf/proto"
|
||
"time"
|
||
)
|
||
|
||
type GameService struct {
|
||
*service.NatsService
|
||
processor *processor.Processor
|
||
bindService *userBindService.UserBindService
|
||
}
|
||
|
||
func NewGameService(param *service.InitNatsServiceParams, cfgRedis *config.Redis) *GameService {
|
||
var err error
|
||
s := new(GameService)
|
||
s.NatsService, err = service.NewNatsService(param)
|
||
if err != nil {
|
||
log.Fatal(err.Error())
|
||
return nil
|
||
}
|
||
var userBindServiceRedis *redis.Client
|
||
userBindServiceRedis, err = db.InitRedis(cfgRedis.Password, cfgRedis.Host, cfgRedis.Port, constant.Redis3UserBindService)
|
||
if err != nil {
|
||
log.Fatal(err.Error())
|
||
return nil
|
||
}
|
||
utils.AutoSetRedisPool(userBindServiceRedis)
|
||
s.bindService = userBindService.NewUserBindService(userBindServiceRedis, s.ServiceEtcd())
|
||
s.processor = processor.NewProcessor()
|
||
return s
|
||
}
|
||
|
||
func (s *GameService) BindService() *userBindService.UserBindService {
|
||
return s.bindService
|
||
}
|
||
|
||
func (s *GameService) Processor() *processor.Processor {
|
||
return s.processor
|
||
}
|
||
|
||
// 依赖子类实现,通过节点id获取topic名再调用SendByTopic
|
||
func (s *GameService) SendByServiceId(serviceId int, msg *ipb.InternalMsg) error {
|
||
node, err := s.findNode(pb.ServiceTypeId(serviceId), msg.UserId)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
topic := service.TopicEx(node.Name)
|
||
return s.SendByTopic(topic, msg)
|
||
}
|
||
|
||
// 向内部服务发送消息
|
||
func (s *GameService) SendServiceData(topic string, connId uint32, userId int64, msgId int32, data []byte) {
|
||
iMsg := ipb.MakeMsg(s.Name(), connId, userId, msgId, data)
|
||
_ = s.SendByTopic(topic, iMsg)
|
||
}
|
||
|
||
// 向内部服务发送消息
|
||
func (s *GameService) SendServiceMsg(sid pb.ServiceTypeId, userId int64, msgId int32, msg proto.Message) {
|
||
node, err := s.findNode(sid, userId)
|
||
if err != nil {
|
||
log.Error(err.Error())
|
||
return
|
||
}
|
||
topic := service.TopicEx(node.Name)
|
||
s.SendServiceMsgByTopic(topic, 0, userId, msgId, msg)
|
||
}
|
||
|
||
func (s *GameService) SendServiceMsgByTopic(topic string, connId uint32, userId int64, msgId int32, msg proto.Message) {
|
||
log.DebugF("send to:%v msg id:%v, msg:%v", topic, pb.MsgId(msgId), msg.String())
|
||
data, _ := proto.Marshal(msg)
|
||
s.SendServiceData(topic, connId, userId, msgId, data)
|
||
}
|
||
|
||
// 向内部服务发送消息
|
||
func (s *GameService) findNode(serviceId pb.ServiceTypeId, uid int64) (*etcd.ServiceNode, error) {
|
||
var err error
|
||
var node *etcd.ServiceNode
|
||
switch s.bindService.CheckServiceNodeStateType(serviceId) {
|
||
case etcd.SNST_Stateful:
|
||
node, err = s.bindService.FindServiceNode(serviceId, uid)
|
||
case etcd.SNST_Stateless:
|
||
node, err = s.bindService.HashServiceNode(serviceId, uid)
|
||
case etcd.SNST_Ordered:
|
||
node, err = s.bindService.HashServiceNode(serviceId, uid)
|
||
default:
|
||
log.ErrorF(s.Log("查找节点类型失败。sid:%v", serviceId))
|
||
return nil, fmt.Errorf(s.Log("查找节点类型失败。sid:%v", serviceId))
|
||
}
|
||
if err != nil {
|
||
return nil, fmt.Errorf(s.Log("查找节点类型失败。sid:%v err:%v", serviceId, err))
|
||
}
|
||
return node, nil
|
||
}
|
||
|
||
// call实现
|
||
func (s *GameService) CallByServiceId(serviceId int, timeout time.Duration, msg *ipb.InternalMsg) (*ipb.InternalMsg, error) {
|
||
node, err := s.findNode(pb.ServiceTypeId(serviceId), msg.UserId)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
topic := service.RpcTopicEx(node.Name)
|
||
return s.CallByTopic(topic, timeout, msg)
|
||
}
|