feat(login): 重构 login 服务启动方式

- 修改 login 服务端口配置,支持动态分配
- 优化 login 服务启动流程,增加信号处理
- 调整 ServerOption 类型,支持 int 类型端口
- 移除 CommendSvrInfo 相关代码,简化结构
- 更新 main 函数,采用新的服务启动方式
This commit is contained in:
2025-07-06 01:49:19 +08:00
parent 86c38fbc84
commit 2f3ca21165
19 changed files with 301 additions and 45 deletions

3
.gitignore vendored
View File

@@ -28,4 +28,5 @@ data/redis/
go.work.sum
__debug_*
public/
frontend/
frontend/
*.exe

13
.vscode/launch.json vendored
View File

@@ -6,7 +6,7 @@
"configurations": [
{
"name": "Launch login",
"name": "Launch login-http",
"type": "go",
"request": "launch",
"mode": "auto",
@@ -19,7 +19,16 @@
"request": "launch",
"mode": "auto",
"cwd": "${workspaceFolder}",
"args": ["-port=27000"],
"args": ["-port=1"],
"program": "${workspaceFolder}/logic"
},
{
"name": "Launch login-tcp",
"type": "go",
"request": "launch",
"mode": "auto",
"cwd": "${workspaceFolder}",
"args": ["-port=0"],
"program": "${workspaceFolder}/logic"
}

50
.vscode/tasks.json vendored Normal file
View File

@@ -0,0 +1,50 @@
{
"version": "2.0.0",
"tasks": [
{
"type": "shell",
"label": "go: build both packages in parallel",
"command": "start /B go build ${workspaceFolder}/login && start /B go build ${workspaceFolder}/logic",
"windows": {
"command": "start /B go build ${workspaceFolder}/login && start /B go build ${workspaceFolder}/logic"
},
"linux": {
"command": "go build ${workspaceFolder}/login & go build ${workspaceFolder}/logic & wait"
},
"osx": {
"command": "go build ${workspaceFolder}/login & go build ${workspaceFolder}/logic & wait"
},
"problemMatcher": [
"$go"
],
"group": "build",
"detail": "Parallel build of login and logic packages"
},
{
"type": "go",
"label": "go: build login",
"command": "build",
"args": [
"${workspaceFolder}/login"
],
"problemMatcher": [
"$go"
],
"group": "build",
"detail": "cd ${workspaceFolder}; go build ${workspaceFolder}/login"
},
{
"type": "go",
"label": "go: build logic",
"command": "build",
"args": [
"${workspaceFolder}/logic"
],
"problemMatcher": [
"$go"
],
"group": "build",
"detail": "cd ${workspaceFolder}; go build ${workspaceFolder}/logic"
}
]
}

View File

@@ -9,7 +9,7 @@ type sConfig struct {
File *file `json:"file,omitempty"` // 文件上传配置
Name string `json:"name"` // 项目名称
Port string `json:"port"`
PortBL string `json:"port_bl"`
PortBL uint32 `json:"port_bl"`
}
// OSS相关配置

View File

@@ -4,6 +4,7 @@ import (
"blazing/common/socket/codec"
"blazing/common/socket/handler"
"github.com/gogf/gf/v2/util/gconv"
"github.com/panjf2000/gnet/pkg/pool/goroutine"
"github.com/panjf2000/gnet/v2"
)
@@ -60,10 +61,10 @@ func WithBufferSize(bufferSize int) Option {
u.bufferSize = bufferSize
}
}
func WithPort(port string) Option {
func WithPort(port int) Option {
return func(s *Server) {
s.network = "tcp"
s.addr = ":" + port
s.addr = ":" + gconv.String(port)
}
}

View File

@@ -0,0 +1,24 @@
package controller
import (
"blazing/common/core"
"blazing/logic/service/server"
"fmt"
"github.com/panjf2000/gnet/v2"
)
// 处理命令: 105
func (h Controller) GetServer(data server.SidInfo, c gnet.Conn) []byte { //这个时候player应该是空的
fmt.Println(data.Sid)
ret := server.NewCommendSvrInfo()
ret.ServerList = server.GetServerInfoList()
tt := core.Pack(data.Head, ret)
//fmt.Println(hex.EncodeToString(tt))
// c.Write(tt)
return tt
}

View File

@@ -1,29 +1,70 @@
package main
import (
"fmt"
"log"
"os"
_ "github.com/gogf/gf/contrib/nosql/redis/v2"
"github.com/gogf/gf/v2/os/gproc"
_ "blazing/contrib/drivers/pgsql"
"github.com/gogf/gf/v2/os/gcmd"
"github.com/gogf/gf/v2/util/gconv"
"blazing/common/socket"
"blazing/common/socket/handler"
"blazing/cool"
"blazing/logic/controller"
//"blazing/o/service"
"blazing/modules/blazing/service"
"github.com/gogf/gf/v2/os/gctx"
)
func signalHandlerForMain(sig os.Signal) {
fmt.Println("MainProcess is shutting down due to signal:", sig.String())
}
func main() {
// 解析命令行参数
cool.Config.PortBL = gcmd.GetOpt("port", "27000").String()
cool.Config.PortBL = gcmd.GetOpt("port", "1").Uint32()
if cool.IsRedisMode {
go cool.ListenFunc(gctx.New())
}
Start(cool.Config.PortBL) //注入service
go Start(cool.Config.PortBL) //注入service
fmt.Println("Process start, pid:", os.Getpid())
gproc.AddSigHandlerShutdown(
signalHandlerForMain,
)
gproc.Listen()
}
func Start(port string) {
// 如果id是0,那就是login server
func Start(serverid uint32) {
head := handler.NewTomeeHandler()
head.Callback = controller.Recv
socket.NewServer(socket.WithPort(port), socket.WithCORS(), socket.WithSocketHandler(head)).Start()
if serverid != 0 {
// 确定端口
port, err := determinePort(serverid)
if err != nil {
log.Fatalf("Failed to determine port: %v", err)
}
//随机端口产生,然后给sql注册端口
service.NewLoginServiceService().SetServerID(serverid, gconv.Uint16(port))
socket.NewServer(socket.WithCORS(), socket.WithPort(port), socket.WithSocketHandler(head)).Start()
} else {
socket.NewServer(socket.WithCORS(), socket.WithPort(defaultPort), socket.WithSocketHandler(head)).Start()
}
}

54
logic/server.go Normal file
View File

@@ -0,0 +1,54 @@
package main
import (
"blazing/cool"
"fmt"
"log"
"math/rand"
"net"
"time"
"github.com/gogf/gf/v2/util/gconv"
)
const (
minRandomPort = 10000
maxRandomPort = 60000
maxPortRetryCount = 5
)
var defaultPort = gconv.Int(cool.Config.Port) //读入默认的端口
// determinePort 确定服务器使用的端口
func determinePort(serverid uint32) (int, error) {
rand.Seed(time.Now().UnixNano())
if serverid == 0 {
return defaultPort, nil
}
for i := 0; i < maxPortRetryCount; i++ {
port := generateRandomPort()
if isPortAvailable(port) {
return port, nil
}
log.Printf("Port %d is not available, retrying...", port)
}
return 0, fmt.Errorf("failed to find available port after %d attempts", maxPortRetryCount)
}
// generateRandomPort 生成指定范围内的随机端口
func generateRandomPort() int {
return minRandomPort + rand.Intn(maxRandomPort-minRandomPort)
}
// isPortAvailable 检查端口是否可用
func isPortAvailable(port int) bool {
address := fmt.Sprintf(":%d", port)
listener, err := net.Listen("tcp", address)
if err != nil {
return false
}
defer listener.Close()
return true
}

View File

@@ -1,9 +1,15 @@
package login
package server
import (
"blazing/cool"
"blazing/modules/base/service"
"blazing/modules/blazing/model"
)
// CommendSvrInfo 初始连接请求信息结构体
type CommendSvrInfo struct {
//Handler handler.TomeeHeader //` struc:"[0]pad"` //消息头 ,这里为传入的头部数据,遍历此头部实现解析CommendSvrInfo
MaxOnlineID uint32 // 最大连接数
MaxOnlineID uint32 `struc:"sizeof=ServerList"` // 最大连接数
IsVip uint32 // 建议为0
ServerInfoLen uint32 `struc:"sizeof=ServerList"` // 服务器信息长度 ServerInfo
ServerList []ServerInfo // 服务器具体信息
@@ -16,7 +22,7 @@ type CommendSvrInfo struct {
func NewCommendSvrInfo() *CommendSvrInfo {
return &CommendSvrInfo{
// Handler: handler.TomeeHeader{},
MaxOnlineID: 100,
// MaxOnlineID: 100,
IsVip: 0,
ServerInfoLen: 0,
ServerList: make([]ServerInfo, 0),
@@ -41,8 +47,42 @@ type ServerInfo struct {
}
// NewServerInfo 创建新的服务器信息实例
func NewServerInfo() *ServerInfo {
return &ServerInfo{}
func newServerInfo() *ServerInfo {
//getServerInfoList()
return &ServerInfo{
//OnlineID: 0,
UserCnt: 20,
//IP: "",
// Port: 0,
Friends: 1,
}
}
func GetServerInfoList() []ServerInfo {
dictInfoModel1 := model.NewServerList()
mType := cool.DBM(dictInfoModel1)
t, _ := mType.All()
//fmt.Println(t)
var ret []model.ServerList
t.Structs(&ret)
//fmt.Println(t)
var ret1 []ServerInfo
ip := service.NewBaseSysConfService().GetValue("server_ip")
for _, v := range ret {
tt := newServerInfo()
tt.OnlineID = v.OnlineID
// tt.UserCnt = v.UserCnt
//tt.IP = v.IP
tt.IP = ip
tt.Port = v.Port
// tt.Friends = v.Friends
ret1 = append(ret1, *tt)
}
return ret1
}
type FriendInfo struct {

View File

@@ -0,0 +1,11 @@
package server
import "blazing/common/socket/handler"
type SidInfo struct { //这里直接使用组合来实现将传入的原始头部数据和结构体参数序列化
Head handler.TomeeHeader `cmd:"105" struc:"[0]pad"` //玩家登录
Sid []byte `struc:"[20]byte"` // 登录会话ID固定长度16字节
// NotLogin uint32 `error="10001"|struc:"[0]pad"` //返回错误码 ,不序列化,仅作为错误码
// ErrorPassWord uint32 `struc:"[0]pad"`
}

View File

@@ -2,13 +2,16 @@ package main
import (
_ "github.com/gogf/gf/contrib/nosql/redis/v2"
"github.com/gogf/gf/v2/util/gconv"
_ "blazing/contrib/drivers/pgsql"
"github.com/panjf2000/gnet/v2"
"blazing/common/core"
"blazing/common/socket"
"blazing/common/socket/handler"
_ "blazing/contrib/files/local"
"blazing/cool"
"blazing/logic/service/login"
// Minio按需启用
@@ -21,8 +24,6 @@ import (
//_ "blazing/contrib/drivers/mysql"
_ "blazing/contrib/drivers/pgsql"
_ "blazing/modules"
"github.com/gogf/gf/v2/os/gctx"
@@ -31,7 +32,7 @@ import (
)
func main() {
go Start(cool.Config.Port)
// go Start(cool.Config.Port)
cmd.Main.Run(gctx.New())
}
@@ -39,21 +40,14 @@ func Start(port string) {
head := handler.NewTomeeHandler()
head.Callback = recv
socket.NewServer(socket.WithPort(port), socket.WithCORS(), socket.WithSocketHandler(head)).Start()
socket.NewServer(socket.WithPort(gconv.Int(port)), socket.WithCORS(), socket.WithSocketHandler(head)).Start()
}
func recv(c gnet.Conn, data handler.TomeeHeader) {
ret := login.NewCommendSvrInfo()
lofin := login.NewServerInfo()
lofin.OnlineID = 1
lofin.UserCnt = 77
lofin.IP = "127.0.0.1"
lofin.Port = 27000
lofin.Friends = 1
//ret.Handler = data
ret.ServerList = append(ret.ServerList, *lofin)
ret.ServerList = login.GetServerInfoList()
tt := core.Pack(data, ret)
//fmt.Println(hex.EncodeToString(tt))

View File

@@ -28,6 +28,7 @@ func init() {
cool.FillInitData(ctx, "base", &model.BaseSysDepartment{})
cool.FillInitData(ctx, "base", &model.BaseSysRoleDepartment{})
cool.FillInitData(ctx, "base", &model.BaseSysParam{})
cool.FillInitData(ctx, "base", &model.BaseSysConf{})
g.Log().Debug(ctx, "module base init finished ...")

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,10 @@
[
{
"id": 1,
"createTime": "2021-02-26 13:53:05.000000",
"updateTime": "2021-03-03 17:50:04.000000",
"cKey": "server_ip",
"cValue": "127.0.0.1"
}
]

View File

@@ -43,7 +43,10 @@ func (s *BaseSysConfService) UpdateValue(cKey, cValue string) error {
// GetValue 获取配置值
func (s *BaseSysConfService) GetValue(cKey string) string {
m := cool.DBM(s.Model).Where("cKey = ?", cKey)
// t1, _ := cool.DBM(s.Model).All()
// fmt.Println(t1)
m := cool.DBM(s.Model).Where("cKey", cKey)
record, err := m.One()
if err != nil {
return ""

View File

@@ -2,7 +2,6 @@ package model
import (
"blazing/cool"
"fmt"
)
const TableNamePet = "pet"
@@ -57,6 +56,11 @@ type PetInfo struct {
FreedTime string `gorm:"comment:'放生时间'" json:"freed_time"`
}
type PetSkillInfo struct {
skill int32 `gorm:"not null;default:0;comment:'技能1'" json:"skill_1_id"`
pp int16 `gorm:"not null;default:0;comment:'技能1PP'" json:"skill_1_pp"`
}
// TableName Pet's table name
func (*Pet) TableName() string {
return TableNamePet
@@ -76,6 +80,6 @@ func NewPet() *Pet {
// init 创建表
func init() {
err := cool.CreateTable(&Pet{})
fmt.Println(err)
_ = cool.CreateTable(&Pet{})
// fmt.Println(err)
}

View File

@@ -9,9 +9,10 @@ const TableNameServerList = "server_list"
// ServerList mapped from table <server_list>
type ServerList struct {
*cool.Model
IP string `gorm:"type:varchar(16);comment:'服务器IP'" json:"ip"`
Port uint16 `gorm:"comment:'端口号,通常是小整数'" json:"port"`
IsOpen bool `gorm:"default:true;not null;comment:'服务器是否开启,默认为开启状态'" json:"is_open"`
OnlineID uint32 `gorm:"column:online_id;comment:'在线ID';uniqueIndex" json:"online_id"`
//IP string `gorm:"type:varchar(16);comment:'服务器IP'" json:"ip"`
Port uint16 `gorm:"comment:'端口号,通常是小整数'" json:"port"`
//IsOpen bool `gorm:"default:true;not null;comment:'服务器是否开启,默认为开启状态'" json:"is_open"`
}
// TableName ServerList's table name

View File

@@ -50,3 +50,24 @@ func (s *LoginService) GetSessionId(accountID uint) (string, string, error) {
// /t1.
// 以上过程只需全局一次且应在生成ID之前完成。
}
func (s *LoginService) SetServerID(OnlineID uint32, Port uint16) error {
m := cool.DBM(s.Model).Where("online_id", OnlineID)
record, err := m.One()
if err != nil {
return err
}
if record == nil {
//说明是新的服务器
_, err := m.InsertAndGetId(&model.ServerList{OnlineID: OnlineID, Port: Port})
return err
}
_, err = m.Data(&model.ServerList{OnlineID: OnlineID, Port: Port}).Where("online_id", OnlineID).Update()
return nil
}

View File

@@ -19,15 +19,6 @@
<RegistSer ip="10.1.1.5" port="3200"/>
</ipConfig>
<ServerList max="300">
<list name="尼尔星1"/>
<list name="尼尔星2"/>
<list name="尼尔星3"/>
<list name="尼尔星4"/>
<list name="尼尔星5"/>
<list name="尼尔星6"/>
<list name="尼尔星7"/>
<list name="尼尔星8"/>
<list name="尼尔星9"/>
<list name="扎克星"/>
<list name="天蝎星"/>
<list name="射手星"/>