mirror of
https://github.com/bufanyun/hotgo.git
synced 2025-08-28 10:09:54 +08:00
发布v2.8.4版本,更新内容请查看:https://github.com/bufanyun/hotgo/tree/v2.0/docs/guide-zh-CN/addon-version-upgrade.md
This commit is contained in:
@@ -1,76 +1,80 @@
|
||||
// Package tcpserver
|
||||
// @Link https://github.com/bufanyun/hotgo
|
||||
// @Copyright Copyright (c) 2023 HotGo CLI
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
|
||||
package tcpserver
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"hotgo/api/servmsg"
|
||||
"hotgo/internal/consts"
|
||||
"hotgo/internal/dao"
|
||||
"hotgo/internal/library/network/tcp"
|
||||
"hotgo/internal/model/entity"
|
||||
"hotgo/internal/model/input/msgin"
|
||||
"hotgo/internal/model/input/servmsgin"
|
||||
"hotgo/internal/service"
|
||||
)
|
||||
|
||||
// OnAuthSummary 获取授权信息
|
||||
func (s *sTCPServer) OnAuthSummary(ctx context.Context, args ...interface{}) {
|
||||
func (s *sTCPServer) OnAuthSummary(ctx context.Context, req *servmsg.AuthSummaryReq) {
|
||||
var (
|
||||
in *msgin.AuthSummary
|
||||
user = tcp.GetCtx(ctx)
|
||||
res = new(msgin.ResponseAuthSummary)
|
||||
conn = tcp.ConnFromCtx(ctx)
|
||||
models *entity.SysServeLicense
|
||||
res = new(servmsg.AuthSummaryRes)
|
||||
)
|
||||
|
||||
if err := gconv.Scan(args, &in); err != nil {
|
||||
res.Code = 1
|
||||
res.Message = err.Error()
|
||||
_ = s.serv.Reply(ctx, res)
|
||||
if conn == nil {
|
||||
g.Log().Warningf(ctx, "conn is nil.")
|
||||
return
|
||||
}
|
||||
|
||||
if user.Auth == nil {
|
||||
res.Code = 2
|
||||
res.Message = "登录信息获取失败,请重新登录"
|
||||
_ = s.serv.Reply(ctx, res)
|
||||
if conn.Auth == nil {
|
||||
res.SetError(gerror.New("登录信息获取失败,请重新登录"))
|
||||
conn.Send(ctx, res)
|
||||
return
|
||||
}
|
||||
|
||||
if err := dao.SysServeLicense.Ctx(ctx).Where("appid = ?", user.Auth.AppId).Scan(&models); err != nil {
|
||||
res.Code = 3
|
||||
res.Message = err.Error()
|
||||
_ = s.serv.Reply(ctx, res)
|
||||
if err := dao.SysServeLicense.Ctx(ctx).Where("appid = ?", conn.Auth.AppId).Scan(&models); err != nil {
|
||||
res.SetError(err)
|
||||
conn.Send(ctx, res)
|
||||
return
|
||||
}
|
||||
|
||||
if models == nil {
|
||||
res.Code = 4
|
||||
res.Message = "授权信息不存在"
|
||||
_ = s.serv.Reply(ctx, res)
|
||||
res.SetError(gerror.New("授权信息不存在"))
|
||||
conn.Send(ctx, res)
|
||||
return
|
||||
}
|
||||
|
||||
if models.Status != consts.StatusEnabled {
|
||||
res.Code = 5
|
||||
res.Message = "授权已禁用,请联系管理员"
|
||||
_ = s.serv.Reply(ctx, res)
|
||||
res.SetError(gerror.New("授权已禁用,请联系管理员"))
|
||||
conn.Send(ctx, res)
|
||||
return
|
||||
}
|
||||
|
||||
if models.Group != user.Auth.Group {
|
||||
res.Code = 6
|
||||
res.Message = "你登录的授权分组未得到授权,请联系管理员"
|
||||
_ = s.serv.Reply(ctx, res)
|
||||
if models.Group != conn.Auth.Group {
|
||||
res.SetError(gerror.New("你登录的授权分组未得到授权,请联系管理员"))
|
||||
conn.Send(ctx, res)
|
||||
return
|
||||
}
|
||||
|
||||
if models.EndAt.Before(gtime.Now()) {
|
||||
res.Code = 7
|
||||
res.Message = "授权已过期,请联系管理员"
|
||||
_ = s.serv.Reply(ctx, res)
|
||||
res.SetError(gerror.New("授权已过期,请联系管理员"))
|
||||
conn.Send(ctx, res)
|
||||
return
|
||||
}
|
||||
|
||||
res.Data = new(msgin.AuthSummaryData)
|
||||
res.Data.EndAt = models.EndAt
|
||||
res.Data.Online = models.Online
|
||||
_ = s.serv.Reply(ctx, res)
|
||||
data := new(servmsgin.AuthSummaryModel)
|
||||
data.EndAt = models.EndAt
|
||||
data.Online = service.TCPServer().Instance().GetAppIdOnline(models.Appid)
|
||||
|
||||
// 请填充你的授权数据
|
||||
// ...
|
||||
|
||||
res.Data = data
|
||||
conn.Send(ctx, res)
|
||||
}
|
||||
|
@@ -1,117 +1,97 @@
|
||||
// Package tcpserver
|
||||
// @Link https://github.com/bufanyun/hotgo
|
||||
// @Copyright Copyright (c) 2023 HotGo CLI
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
|
||||
package tcpserver
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"hotgo/api/servmsg"
|
||||
"hotgo/internal/consts"
|
||||
"hotgo/internal/model/input/msgin"
|
||||
)
|
||||
|
||||
// CronDelete 删除任务
|
||||
func (s *sTCPServer) CronDelete(ctx context.Context, in *msgin.CronDelete) (err error) {
|
||||
clients := s.serv.GetGroupClients(consts.TCPClientGroupCron)
|
||||
func (s *sTCPServer) CronDelete(ctx context.Context, in *servmsg.CronDeleteReq) (err error) {
|
||||
clients := s.serv.GetGroupClients(consts.LicenseGroupCron)
|
||||
if len(clients) == 0 {
|
||||
err = gerror.New("没有在线的定时任务服务")
|
||||
return
|
||||
}
|
||||
|
||||
for _, client := range clients {
|
||||
res, err := s.serv.RpcRequest(ctx, client, in)
|
||||
if err != nil {
|
||||
return err
|
||||
var res servmsg.CronDeleteRes
|
||||
if err = s.serv.RequestScan(ctx, client, in, &res); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var resp = new(msgin.ResponseCronDelete)
|
||||
if err = gconv.Scan(res, &resp); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = resp.GetError(); err != nil {
|
||||
return err
|
||||
if err = res.GetError(); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// CronEdit 编辑任务
|
||||
func (s *sTCPServer) CronEdit(ctx context.Context, in *msgin.CronEdit) (err error) {
|
||||
clients := s.serv.GetGroupClients(consts.TCPClientGroupCron)
|
||||
func (s *sTCPServer) CronEdit(ctx context.Context, in *servmsg.CronEditReq) (err error) {
|
||||
clients := s.serv.GetGroupClients(consts.LicenseGroupCron)
|
||||
if len(clients) == 0 {
|
||||
err = gerror.New("没有在线的定时任务服务")
|
||||
return
|
||||
}
|
||||
|
||||
for _, client := range clients {
|
||||
res, err := s.serv.RpcRequest(ctx, client, in)
|
||||
if err != nil {
|
||||
return err
|
||||
var res servmsg.CronEditRes
|
||||
if err = s.serv.RequestScan(ctx, client, in, &res); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var resp = new(msgin.ResponseCronEdit)
|
||||
if err = gconv.Scan(res, &resp); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = resp.GetError(); err != nil {
|
||||
return err
|
||||
if err = res.GetError(); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// CronStatus 修改任务状态
|
||||
func (s *sTCPServer) CronStatus(ctx context.Context, in *msgin.CronStatus) (err error) {
|
||||
clients := s.serv.GetGroupClients(consts.TCPClientGroupCron)
|
||||
func (s *sTCPServer) CronStatus(ctx context.Context, in *servmsg.CronStatusReq) (err error) {
|
||||
clients := s.serv.GetGroupClients(consts.LicenseGroupCron)
|
||||
if len(clients) == 0 {
|
||||
err = gerror.New("没有在线的定时任务服务")
|
||||
return
|
||||
}
|
||||
|
||||
for _, client := range clients {
|
||||
res, err := s.serv.RpcRequest(ctx, client, in)
|
||||
if err != nil {
|
||||
return err
|
||||
var res servmsg.CronStatusRes
|
||||
if err = s.serv.RequestScan(ctx, client, in, &res); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var resp = new(msgin.ResponseCronStatus)
|
||||
if err = gconv.Scan(res, &resp); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = resp.GetError(); err != nil {
|
||||
return err
|
||||
if err = res.GetError(); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// CronOnlineExec 执行一次任务
|
||||
func (s *sTCPServer) CronOnlineExec(ctx context.Context, in *msgin.CronOnlineExec) (err error) {
|
||||
clients := s.serv.GetGroupClients(consts.TCPClientGroupCron)
|
||||
func (s *sTCPServer) CronOnlineExec(ctx context.Context, in *servmsg.CronOnlineExecReq) (err error) {
|
||||
clients := s.serv.GetGroupClients(consts.LicenseGroupCron)
|
||||
if len(clients) == 0 {
|
||||
err = gerror.New("没有在线的定时任务服务")
|
||||
return
|
||||
}
|
||||
|
||||
for _, client := range clients {
|
||||
res, err := s.serv.RpcRequest(ctx, client, in)
|
||||
if err != nil {
|
||||
return err
|
||||
var res servmsg.CronOnlineExecRes
|
||||
if err = s.serv.RequestScan(ctx, client, in, &res); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var resp = new(msgin.ResponseCronOnlineExec)
|
||||
if err = gconv.Scan(res, &resp); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = resp.GetError(); err != nil {
|
||||
return err
|
||||
if err = res.GetError(); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
49
server/internal/logic/tcpserver/example_handle.go
Normal file
49
server/internal/logic/tcpserver/example_handle.go
Normal file
@@ -0,0 +1,49 @@
|
||||
package tcpserver
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"hotgo/api/servmsg"
|
||||
"hotgo/internal/consts"
|
||||
"hotgo/internal/library/network/tcp"
|
||||
"hotgo/internal/model/input/servmsgin"
|
||||
)
|
||||
|
||||
// OnExampleHello 一个tcp请求例子
|
||||
func (s *sTCPServer) OnExampleHello(ctx context.Context, req *servmsg.ExampleHelloReq) {
|
||||
var (
|
||||
conn = tcp.ConnFromCtx(ctx)
|
||||
res = new(servmsg.ExampleHelloRes)
|
||||
data = new(servmsgin.ExampleHelloModel)
|
||||
)
|
||||
|
||||
if conn == nil {
|
||||
g.Log().Warningf(ctx, "conn is nil.")
|
||||
return
|
||||
}
|
||||
|
||||
if conn.Auth == nil {
|
||||
res.SetError(gerror.New("连接未认证,请确认已登录成功!"))
|
||||
conn.Send(ctx, res)
|
||||
return
|
||||
}
|
||||
|
||||
data.Desc = fmt.Sprintf("Hello %v, 你的APPID:%v,当前HotGo版本:%v,你成功请求了`servmsg.ExampleHelloReq`接口!", req.Name, conn.Auth.AppId, consts.VersionApp)
|
||||
data.Timestamp = gtime.Now()
|
||||
res.Data = data
|
||||
conn.Send(ctx, res)
|
||||
}
|
||||
|
||||
// OnExampleRPCHello 一个rpc请求例子
|
||||
func (s *sTCPServer) OnExampleRPCHello(ctx context.Context, req *servmsg.ExampleRPCHelloReq) (res *servmsg.ExampleRPCHelloRes, err error) {
|
||||
var data = new(servmsgin.ExampleHelloModel)
|
||||
data.Desc = fmt.Sprintf("Hello %v, 当前HotGo版本:%v,你成功请求了`servmsg.ExampleRPCHelloReq`接口!", req.Name, consts.VersionApp)
|
||||
data.Timestamp = gtime.Now()
|
||||
|
||||
res = new(servmsg.ExampleRPCHelloRes)
|
||||
res.Data = data
|
||||
return
|
||||
}
|
@@ -1,3 +1,8 @@
|
||||
// Package tcpserver
|
||||
// @Link https://github.com/bufanyun/hotgo
|
||||
// @Copyright Copyright (c) 2023 HotGo CLI
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
|
||||
package tcpserver
|
||||
|
||||
import (
|
||||
@@ -20,40 +25,39 @@ func newTCPServer() *sTCPServer {
|
||||
return &sTCPServer{}
|
||||
}
|
||||
|
||||
// Instance 获取实例
|
||||
func (s *sTCPServer) Instance() *tcp.Server {
|
||||
return s.serv
|
||||
}
|
||||
|
||||
// Start 启动服务
|
||||
func (s *sTCPServer) Start(ctx context.Context) {
|
||||
simple.SafeGo(ctx, func(ctx context.Context) {
|
||||
g.Log().Debug(ctx, "TCPServer start..")
|
||||
|
||||
server, err := tcp.NewServer(&tcp.ServerConfig{
|
||||
s.serv = tcp.NewServer(&tcp.ServerConfig{
|
||||
Name: simple.AppName(ctx),
|
||||
Addr: g.Cfg().MustGet(ctx, "tcp.server.address").String(),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
g.Log().Warningf(ctx, "TCPServer start fail:%+v", err)
|
||||
return
|
||||
}
|
||||
// 注册路由
|
||||
s.serv.RegisterRouter(
|
||||
s.onServerLogin, // 服务登录
|
||||
s.onServerHeartbeat, // 心跳
|
||||
s.OnAuthSummary, // 获取授权信息
|
||||
s.OnExampleHello, // 一个tcp请求例子
|
||||
)
|
||||
|
||||
s.serv = server
|
||||
// 注册RPC路由
|
||||
s.serv.RegisterRPCRouter(
|
||||
s.OnExampleRPCHello, // 一个rpc请求例子
|
||||
)
|
||||
|
||||
// 消息队列路由
|
||||
s.serv.RegisterQueueRouter(map[string]tcp.RouterHandler{
|
||||
// ...
|
||||
})
|
||||
|
||||
// 定时任务路由
|
||||
s.serv.RegisterCronRouter(map[string]tcp.RouterHandler{
|
||||
// ...
|
||||
})
|
||||
|
||||
// 授权服务路由
|
||||
s.serv.RegisterAuthRouter(map[string]tcp.RouterHandler{
|
||||
"AuthSummary": s.OnAuthSummary, // 获取授权信息
|
||||
})
|
||||
// 注册拦截器
|
||||
s.serv.RegisterInterceptor(s.DefaultInterceptor, s.PreFilterInterceptor)
|
||||
|
||||
// 服务监听
|
||||
if err = s.serv.Listen(); err != nil {
|
||||
if err := s.serv.Listen(); err != nil {
|
||||
if !s.serv.IsClose() {
|
||||
g.Log().Warningf(ctx, "TCPServer Listen err:%v", err)
|
||||
}
|
||||
|
167
server/internal/logic/tcpserver/server_handle.go
Normal file
167
server/internal/logic/tcpserver/server_handle.go
Normal file
@@ -0,0 +1,167 @@
|
||||
// Package tcpserver
|
||||
// @Link https://github.com/bufanyun/hotgo
|
||||
// @Copyright Copyright (c) 2023 HotGo CLI
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
|
||||
package tcpserver
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
"hotgo/internal/consts"
|
||||
"hotgo/internal/dao"
|
||||
"hotgo/internal/library/network/tcp"
|
||||
"hotgo/internal/model/entity"
|
||||
"hotgo/utility/convert"
|
||||
"hotgo/utility/encrypt"
|
||||
)
|
||||
|
||||
// onServerLogin 处理客户端登录
|
||||
func (s *sTCPServer) onServerLogin(ctx context.Context, req *tcp.ServerLoginReq) {
|
||||
var (
|
||||
conn = tcp.ConnFromCtx(ctx)
|
||||
models *entity.SysServeLicense
|
||||
res = new(tcp.ServerLoginRes)
|
||||
cols = dao.SysServeLicense.Columns()
|
||||
)
|
||||
|
||||
if conn == nil {
|
||||
g.Log().Warningf(ctx, "conn is nil.")
|
||||
return
|
||||
}
|
||||
|
||||
if err := dao.SysServeLicense.Ctx(ctx).Where(cols.Appid, req.AppId).Scan(&models); err != nil {
|
||||
return
|
||||
}
|
||||
if models == nil {
|
||||
res.SetError(gerror.New("授权信息不存在"))
|
||||
conn.Send(ctx, res)
|
||||
return
|
||||
}
|
||||
|
||||
// 验证签名
|
||||
sign := encrypt.Md5ToString(fmt.Sprintf("%v%v%v", models.Appid, req.Timestamp, models.SecretKey))
|
||||
if sign != req.Sign {
|
||||
res.SetError(gerror.New("签名错误,请检查!"))
|
||||
conn.Send(ctx, res)
|
||||
return
|
||||
}
|
||||
|
||||
if models.Status != consts.StatusEnabled {
|
||||
res.SetError(gerror.New("授权已禁用,请联系管理员"))
|
||||
conn.Send(ctx, res)
|
||||
return
|
||||
}
|
||||
|
||||
if models.Group != req.Group {
|
||||
res.SetError(gerror.New("你登录的授权分组未得到授权,请联系管理员"))
|
||||
conn.Send(ctx, res)
|
||||
return
|
||||
}
|
||||
|
||||
if models.EndAt.Before(gtime.Now()) {
|
||||
res.SetError(gerror.New("授权已过期,请联系管理员"))
|
||||
conn.Send(ctx, res)
|
||||
return
|
||||
}
|
||||
|
||||
ip := gstr.StrTillEx(conn.RemoteAddr().String(), ":")
|
||||
if !convert.MatchIpStrategy(models.AllowedIps, ip) {
|
||||
res.SetError(gerror.New("IP(" + ip + ")未授权,请联系管理员"))
|
||||
conn.Send(ctx, res)
|
||||
return
|
||||
}
|
||||
|
||||
var routes []string
|
||||
if err := models.Routes.Scan(&routes); err != nil {
|
||||
res.SetError(gerror.New("授权路由解析失败,请联系管理员"))
|
||||
conn.Send(ctx, res)
|
||||
return
|
||||
}
|
||||
|
||||
// 拿出当前登录应用的所有客户端
|
||||
clients := s.serv.GetAppIdClients(models.Appid)
|
||||
|
||||
// 检查多地登录,如果连接超过上限,则断开当前许可证下的所有连接
|
||||
if len(clients)+1 > models.OnlineLimit {
|
||||
for _, client := range clients {
|
||||
client.Close()
|
||||
}
|
||||
res.SetError(gerror.New("授权登录端超出上限,请勿多地登录"))
|
||||
conn.Send(ctx, res)
|
||||
return
|
||||
}
|
||||
|
||||
for _, client := range clients {
|
||||
if client.Auth.Name == req.Name {
|
||||
res.SetError(gerror.Newf("应用名称[%v]已存在登录用户,当前连接已被拒绝。", req.Name))
|
||||
conn.Send(ctx, res)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
auth := &tcp.AuthMeta{
|
||||
Name: req.Name,
|
||||
Extra: req.Extra,
|
||||
Group: models.Group,
|
||||
AppId: models.Appid,
|
||||
SecretKey: models.SecretKey,
|
||||
EndAt: models.EndAt,
|
||||
Routes: routes,
|
||||
}
|
||||
s.serv.AuthClient(conn, auth)
|
||||
|
||||
update := g.Map{
|
||||
cols.LoginTimes: models.LoginTimes + 1,
|
||||
cols.LastLoginAt: gtime.Now(),
|
||||
cols.LastActiveAt: gtime.Now(),
|
||||
cols.RemoteAddr: conn.RemoteAddr().String(),
|
||||
}
|
||||
if _, err := dao.SysServeLicense.Ctx(ctx).Where(cols.Id, models.Id).Data(update).Update(); err != nil {
|
||||
res.SetError(err)
|
||||
conn.Send(ctx, res)
|
||||
return
|
||||
}
|
||||
|
||||
g.Log().Debugf(ctx, "onServerLogin succeed. appid:%v, group:%v, name:%v", auth.AppId, auth.Group, auth.Name)
|
||||
conn.Send(ctx, res)
|
||||
}
|
||||
|
||||
// onServerHeartbeat 处理客户端心跳
|
||||
func (s *sTCPServer) onServerHeartbeat(ctx context.Context, req *tcp.ServerHeartbeatReq) {
|
||||
var (
|
||||
conn = tcp.ConnFromCtx(ctx)
|
||||
res = new(tcp.ServerHeartbeatRes)
|
||||
)
|
||||
|
||||
if conn == nil {
|
||||
g.Log().Warningf(ctx, "conn is nil.")
|
||||
return
|
||||
}
|
||||
|
||||
client := s.serv.GetClient(conn.Conn)
|
||||
if client == nil {
|
||||
res.SetError(gerror.New("登录异常,请重新登录"))
|
||||
conn.Send(ctx, res)
|
||||
return
|
||||
}
|
||||
|
||||
// 更新心跳
|
||||
client.Heartbeat = gtime.Timestamp()
|
||||
|
||||
// 更新活跃时间
|
||||
update := g.Map{
|
||||
dao.SysServeLicense.Columns().LastActiveAt: gtime.Now(),
|
||||
}
|
||||
if _, err := dao.SysServeLicense.Ctx(ctx).Where(dao.SysServeLicense.Columns().Appid, client.Auth.AppId).Data(update).Update(); err != nil {
|
||||
res.SetError(err)
|
||||
conn.Send(ctx, res)
|
||||
return
|
||||
}
|
||||
|
||||
conn.Send(ctx, res)
|
||||
}
|
75
server/internal/logic/tcpserver/server_interceptor.go
Normal file
75
server/internal/logic/tcpserver/server_interceptor.go
Normal file
@@ -0,0 +1,75 @@
|
||||
// Package tcpserver
|
||||
// @Link https://github.com/bufanyun/hotgo
|
||||
// @Copyright Copyright (c) 2023 HotGo CLI
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
|
||||
package tcpserver
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/errors/gcode"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"hotgo/internal/library/network/tcp"
|
||||
"hotgo/utility/validate"
|
||||
)
|
||||
|
||||
// 免登录路由
|
||||
var noLoginRouter = map[string]struct{}{
|
||||
"ServerLoginReq": {}, // 服务登录
|
||||
}
|
||||
|
||||
// 免验证路由
|
||||
var noVerifyRouter = map[string]struct{}{
|
||||
"ServerHeartbeatReq": {}, // 心跳
|
||||
}
|
||||
|
||||
func (s *sTCPServer) isNoLoginRouter(router string) bool {
|
||||
_, ok := noLoginRouter[router]
|
||||
return ok
|
||||
}
|
||||
|
||||
func (s *sTCPServer) isNoVerifyRouter(router string) bool {
|
||||
_, ok := noVerifyRouter[router]
|
||||
return ok
|
||||
}
|
||||
|
||||
// DefaultInterceptor 默认拦截器
|
||||
func (s *sTCPServer) DefaultInterceptor(ctx context.Context, msg *tcp.Message) (err error) {
|
||||
conn := tcp.ConnFromCtx(ctx)
|
||||
//g.Log().Debugf(ctx, "DefaultInterceptor msg:%+v, conn:%+v", msg, gjson.New(conn).String())
|
||||
|
||||
// 免登录
|
||||
if s.isNoLoginRouter(msg.Router) {
|
||||
return
|
||||
}
|
||||
|
||||
if conn.Auth == nil {
|
||||
err = gerror.NewCode(gcode.CodeNotAuthorized, "未进行登录认证,请先登录")
|
||||
return
|
||||
}
|
||||
|
||||
// 检查授权有效期
|
||||
if conn.Auth.EndAt.Before(gtime.Now()) {
|
||||
err = gerror.NewCode(gcode.CodeNotAuthorized, "授权已过期")
|
||||
return
|
||||
}
|
||||
|
||||
// 免验证
|
||||
if s.isNoVerifyRouter(msg.Router) {
|
||||
return
|
||||
}
|
||||
|
||||
// 验证路由权限
|
||||
if len(conn.Auth.Routes) > 0 && !validate.InSlice(conn.Auth.Routes, msg.Router) {
|
||||
err = gerror.NewCodef(gcode.CodeNotAuthorized, "没有授权路由访问权限:%v", msg.Router)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// PreFilterInterceptor 预处理
|
||||
func (s *sTCPServer) PreFilterInterceptor(ctx context.Context, msg *tcp.Message) (err error) {
|
||||
//g.Log().Debug(ctx, "PreFilterInterceptor...")
|
||||
return
|
||||
}
|
Reference in New Issue
Block a user