完善重连流程

This commit is contained in:
flswld
2023-02-05 08:44:07 +08:00
parent 053990a33c
commit 3f0b57721f
4 changed files with 80 additions and 9 deletions

View File

@@ -5,7 +5,7 @@ client_proto_proxy_enable = false
version = "300,310,320" # 支持的客户端协议版本号 三位数字 多个以逗号分隔 如300,310,320 version = "300,310,320" # 支持的客户端协议版本号 三位数字 多个以逗号分隔 如300,310,320
gate_tcp_mq_addr = "127.0.0.1" # 访问网关tcp直连消息队列的地址 填网关的内网地址 gate_tcp_mq_addr = "127.0.0.1" # 访问网关tcp直连消息队列的地址 填网关的内网地址
gate_tcp_mq_port = 33333 gate_tcp_mq_port = 33333
login_sdk_url = "http://127.0.0.1:8080/gate/token/verify" # 网关登录验证token的sdk服务器地址 目前填dispatch的内网地址 login_sdk_url = "http://127.0.0.1:8080" # 网关登录验证token的sdk服务器地址 目前填dispatch的内网地址
[logger] [logger]
level = "DEBUG" level = "DEBUG"

View File

@@ -139,6 +139,7 @@ func (c *Controller) registerRouter() {
} }
engine.Use(c.authorize()) engine.Use(c.authorize())
engine.POST("/gate/token/verify", c.gateTokenVerify) engine.POST("/gate/token/verify", c.gateTokenVerify)
engine.POST("/gate/token/reset", c.gateTokenReset)
port := config.CONF.HttpPort port := config.CONF.HttpPort
addr := ":" + strconv.Itoa(int(port)) addr := ":" + strconv.Itoa(int(port))
err := engine.Run(addr) err := engine.Run(addr)

View File

@@ -67,3 +67,32 @@ func (c *Controller) gateTokenVerify(context *gin.Context) {
PlayerID: uint32(account.PlayerID), PlayerID: uint32(account.PlayerID),
}) })
} }
type TokenResetReq struct {
PlayerId uint32 `json:"playerId"`
}
type TokenResetRsp struct {
Result bool `json:"result"`
}
func (c *Controller) gateTokenReset(context *gin.Context) {
req := new(TokenResetReq)
err := context.ShouldBindJSON(req)
if err != nil {
context.JSON(http.StatusOK, &TokenResetRsp{
Result: false,
})
return
}
_, err = c.dao.UpdateAccountFieldByFieldName("PlayerID", req.PlayerId, "comboTokenUsed", false)
if err != nil {
context.JSON(http.StatusOK, &TokenResetRsp{
Result: false,
})
return
}
context.JSON(http.StatusOK, &TokenResetRsp{
Result: true,
})
}

View File

@@ -169,7 +169,6 @@ func (k *KcpConnectManager) sendMsgHandle() {
logger.Error("kcpRawSendChan is full, convId: %v", protoMsg.ConvId) logger.Error("kcpRawSendChan is full, convId: %v", protoMsg.ConvId)
return return
} }
kcpRawSendChan <- protoMsg
if protoMsg.CmdId == cmd.PlayerLoginRsp { if protoMsg.CmdId == cmd.PlayerLoginRsp {
logger.Debug("session active, convId: %v", protoMsg.ConvId) logger.Debug("session active, convId: %v", protoMsg.ConvId)
session.connState = ConnActive session.connState = ConnActive
@@ -188,7 +187,30 @@ func (k *KcpConnectManager) sendMsgHandle() {
EventId: mq.ServerAppidBindNotify, EventId: mq.ServerAppidBindNotify,
ServerMsg: serverMsg, ServerMsg: serverMsg,
}) })
} else if protoMsg.CmdId == cmd.ClientReconnectNotify {
tokenResetRsp, err := httpclient.Post[controller.TokenResetRsp](config.CONF.Hk4e.LoginSdkUrl+"/gate/token/reset", &controller.TokenResetReq{
PlayerId: session.userId,
}, "")
if err != nil {
logger.Error("reset token error: %v", err)
k.kcpEventInput <- &KcpEvent{
ConvId: protoMsg.ConvId,
EventId: KcpConnForceClose,
EventMessage: uint32(kcp.EnetServerKick),
} }
return
}
if !tokenResetRsp.Result {
logger.Error("reset token fail")
k.kcpEventInput <- &KcpEvent{
ConvId: protoMsg.ConvId,
EventId: KcpConnForceClose,
EventMessage: uint32(kcp.EnetServerKick),
}
return
}
}
kcpRawSendChan <- protoMsg
} }
for { for {
select { select {
@@ -279,16 +301,25 @@ func (k *KcpConnectManager) getHeadMsg(clientSeq uint32) (headMsg *proto.PacketH
} }
func (k *KcpConnectManager) getPlayerToken(req *proto.GetPlayerTokenReq, session *Session) (rsp *proto.GetPlayerTokenRsp) { func (k *KcpConnectManager) getPlayerToken(req *proto.GetPlayerTokenReq, session *Session) (rsp *proto.GetPlayerTokenRsp) {
tokenVerifyRsp, err := httpclient.Post[controller.TokenVerifyRsp](config.CONF.Hk4e.LoginSdkUrl, &controller.TokenVerifyReq{ loginFail := func() {
k.kcpEventInput <- &KcpEvent{
ConvId: session.conn.GetConv(),
EventId: KcpConnForceClose,
EventMessage: uint32(kcp.EnetLoginUnfinished),
}
}
tokenVerifyRsp, err := httpclient.Post[controller.TokenVerifyRsp](config.CONF.Hk4e.LoginSdkUrl+"/gate/token/verify", &controller.TokenVerifyReq{
AccountId: req.AccountUid, AccountId: req.AccountUid,
AccountToken: req.AccountToken, AccountToken: req.AccountToken,
}, "") }, "")
if err != nil { if err != nil {
logger.Error("verify token error: %v", err) logger.Error("verify token error: %v", err)
loginFail()
return nil return nil
} }
if !tokenVerifyRsp.Valid { if !tokenVerifyRsp.Valid {
logger.Error("token error") logger.Error("token error")
loginFail()
return nil return nil
} }
// comboToken验证成功 // comboToken验证成功
@@ -343,6 +374,7 @@ func (k *KcpConnectManager) getPlayerToken(req *proto.GetPlayerTokenReq, session
}) })
if err != nil { if err != nil {
logger.Error("get gs server appid error: %v", err) logger.Error("get gs server appid error: %v", err)
loginFail()
return nil return nil
} }
session.gsServerAppId = gsServerAppId.AppId session.gsServerAppId = gsServerAppId.AppId
@@ -392,52 +424,61 @@ func (k *KcpConnectManager) getPlayerToken(req *proto.GetPlayerTokenReq, session
encPubPrivKey, exist := k.encRsaKeyMap[keyId] encPubPrivKey, exist := k.encRsaKeyMap[keyId]
if !exist { if !exist {
logger.Error("can not found key id: %v", keyId) logger.Error("can not found key id: %v", keyId)
return loginFail()
return nil
} }
pubKey, err := endec.RsaParsePubKeyByPrivKey(encPubPrivKey) pubKey, err := endec.RsaParsePubKeyByPrivKey(encPubPrivKey)
if err != nil { if err != nil {
logger.Error("parse rsa pub key error: %v", err) logger.Error("parse rsa pub key error: %v", err)
loginFail()
return nil return nil
} }
signPrivkey, err := endec.RsaParsePrivKey(k.signRsaKey) signPrivkey, err := endec.RsaParsePrivKey(k.signRsaKey)
if err != nil { if err != nil {
logger.Error("parse rsa priv key error: %v", err) logger.Error("parse rsa priv key error: %v", err)
loginFail()
return nil return nil
} }
clientSeedBase64 := req.GetClientRandKey() clientSeedBase64 := req.GetClientRandKey()
clientSeedEnc, err := base64.StdEncoding.DecodeString(clientSeedBase64) clientSeedEnc, err := base64.StdEncoding.DecodeString(clientSeedBase64)
if err != nil { if err != nil {
logger.Error("parse client seed base64 error: %v", err) logger.Error("parse client seed base64 error: %v", err)
loginFail()
return nil return nil
} }
clientSeed, err := endec.RsaDecrypt(clientSeedEnc, signPrivkey) clientSeed, err := endec.RsaDecrypt(clientSeedEnc, signPrivkey)
if err != nil { if err != nil {
logger.Error("rsa dec error: %v", err) logger.Error("rsa dec error: %v", err)
return rsp loginFail()
return nil
} }
clientSeedUint64 := uint64(0) clientSeedUint64 := uint64(0)
err = binary.Read(bytes.NewReader(clientSeed), binary.BigEndian, &clientSeedUint64) err = binary.Read(bytes.NewReader(clientSeed), binary.BigEndian, &clientSeedUint64)
if err != nil { if err != nil {
logger.Error("parse client seed to uint64 error: %v", err) logger.Error("parse client seed to uint64 error: %v", err)
return rsp loginFail()
return nil
} }
seedUint64 := serverSeedUint64 ^ clientSeedUint64 seedUint64 := serverSeedUint64 ^ clientSeedUint64
seedBuf := new(bytes.Buffer) seedBuf := new(bytes.Buffer)
err = binary.Write(seedBuf, binary.BigEndian, seedUint64) err = binary.Write(seedBuf, binary.BigEndian, seedUint64)
if err != nil { if err != nil {
logger.Error("conv seed uint64 to bytes error: %v", err) logger.Error("conv seed uint64 to bytes error: %v", err)
return rsp loginFail()
return nil
} }
seed := seedBuf.Bytes() seed := seedBuf.Bytes()
seedEnc, err := endec.RsaEncrypt(seed, pubKey) seedEnc, err := endec.RsaEncrypt(seed, pubKey)
if err != nil { if err != nil {
logger.Error("rsa enc error: %v", err) logger.Error("rsa enc error: %v", err)
return rsp loginFail()
return nil
} }
seedSign, err := endec.RsaSign(seed, signPrivkey) seedSign, err := endec.RsaSign(seed, signPrivkey)
if err != nil { if err != nil {
logger.Error("rsa sign error: %v", err) logger.Error("rsa sign error: %v", err)
return rsp loginFail()
return nil
} }
rsp.KeyId = req.KeyId rsp.KeyId = req.KeyId
rsp.ServerRandKey = base64.StdEncoding.EncodeToString(seedEnc) rsp.ServerRandKey = base64.StdEncoding.EncodeToString(seedEnc)