修复CPU占用问题,添加servers.JOIN,LEAVE,LIST包
This commit is contained in:
@ -3,6 +3,7 @@ package minecraft
|
||||
import (
|
||||
"coreapp/util"
|
||||
"coreapp/util/ws"
|
||||
"fmt"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gorilla/websocket"
|
||||
"google.golang.org/protobuf/proto"
|
||||
@ -41,14 +42,15 @@ func (typ ServerType) Prefix() string {
|
||||
}
|
||||
|
||||
type Server struct {
|
||||
Id string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Group string `json:"group"`
|
||||
Host string `json:"host"`
|
||||
Port int `json:"port"`
|
||||
Type ServerType `json:"type"`
|
||||
Motd string `json:"motd"`
|
||||
LastHB time.Time
|
||||
Id string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Group string `json:"group"`
|
||||
Host string `json:"host"`
|
||||
Port int `json:"port"`
|
||||
Type ServerType `json:"type"`
|
||||
Motd string `json:"motd"`
|
||||
Players []string `json:"players"`
|
||||
LastHB time.Time
|
||||
}
|
||||
|
||||
var servers = sync.Map{}
|
||||
@ -88,11 +90,12 @@ func ServerMiddleware() gin.HandlerFunc {
|
||||
}
|
||||
|
||||
func ServerList(c *gin.Context) {
|
||||
serverList := make(map[string]*Server)
|
||||
var serverList []Server
|
||||
|
||||
// 遍历 sync.Map
|
||||
servers.Range(func(key, value interface{}) bool {
|
||||
serverList[key.(string)] = value.(*Server)
|
||||
server := value.(*Server)
|
||||
serverList = append(serverList, *server)
|
||||
return true // 继续遍历
|
||||
})
|
||||
|
||||
@ -104,12 +107,12 @@ func ServerList(c *gin.Context) {
|
||||
}
|
||||
|
||||
type ServerRegisterData struct {
|
||||
Name string `json:"name"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Host string `json:"host"`
|
||||
Port int `json:"port"`
|
||||
Type ServerType `json:"type"`
|
||||
Group string `json:"group"`
|
||||
Motd string `json:"motd"`
|
||||
Group string `json:"group,omitempty"`
|
||||
Motd string `json:"motd,omitempty"`
|
||||
}
|
||||
|
||||
func ServerRegister(c *gin.Context) {
|
||||
@ -223,6 +226,23 @@ func ServerMessage(c *gin.Context) {
|
||||
if c.GetString("serverId") == "PROXY" {
|
||||
serverProxyConn = wrapped
|
||||
serverProxyLastHB = time.Now()
|
||||
servers.Range(func(_, value any) bool {
|
||||
server := value.(*Server)
|
||||
newPkt := &ServerNewPacket{
|
||||
ServerId: server.Id,
|
||||
Name: server.Name,
|
||||
Host: server.Host,
|
||||
Port: int32(server.Port),
|
||||
Group: server.Group,
|
||||
Motd: server.Motd,
|
||||
}
|
||||
buf, err := serverWrapPacket(ServerPacketType_NEW, newPkt)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
wrapped.WriteChan <- ws.Binary(buf)
|
||||
return true
|
||||
})
|
||||
go serverProxyReadLoop(wrapped)
|
||||
} else {
|
||||
go serverReadLoop(wrapped, c.GetString("serverId"))
|
||||
@ -230,6 +250,9 @@ func ServerMessage(c *gin.Context) {
|
||||
}
|
||||
|
||||
func serverReadLoop(conn *ws.Conn, serverId string) {
|
||||
defer func() {
|
||||
fmt.Printf("%s closed\n", serverId)
|
||||
}()
|
||||
for {
|
||||
// 使用 Load 读取,避免并发问题
|
||||
serverVal, ok := servers.Load(serverId)
|
||||
@ -266,6 +289,43 @@ func serverReadLoop(conn *ws.Conn, serverId string) {
|
||||
if serverProxyConn != nil {
|
||||
serverProxyConn.WriteChan <- ws.Binary(msg)
|
||||
}
|
||||
case ServerPacketType_JOIN:
|
||||
var payload ServerPlayerPacket
|
||||
err := proto.Unmarshal(pkt.GetPayload(), &payload)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
server.Players = append(server.Players, payload.Player)
|
||||
case ServerPacketType_LEAVE:
|
||||
var payload ServerPlayerPacket
|
||||
err := proto.Unmarshal(pkt.GetPayload(), &payload)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
for i, player := range server.Players {
|
||||
if player == payload.Player {
|
||||
server.Players = append(server.Players[:i], server.Players[i+1:]...)
|
||||
break
|
||||
}
|
||||
}
|
||||
case ServerPacketType_LIST:
|
||||
var payload ServerListPacket
|
||||
err := proto.Unmarshal(pkt.GetPayload(), &payload)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
reply := &ServerListPacket{
|
||||
ServerId: payload.ServerId,
|
||||
}
|
||||
if s, ok := servers.Load(payload.ServerId); ok {
|
||||
reply.Players = s.(*Server).Players
|
||||
buf, err := proto.Marshal(reply)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
conn.WriteChan <- ws.Binary(buf)
|
||||
return
|
||||
}
|
||||
}
|
||||
default:
|
||||
if conn.IsClosed() {
|
||||
@ -280,28 +340,26 @@ func serverProxyReadLoop(conn *ws.Conn) {
|
||||
serverProxyConn = nil
|
||||
}()
|
||||
for {
|
||||
select {
|
||||
case msg := <-conn.ReadChan:
|
||||
if msg == nil {
|
||||
return
|
||||
msg := <-conn.ReadChan
|
||||
if msg == nil {
|
||||
return
|
||||
}
|
||||
pkt := &ServerPacket{}
|
||||
err := proto.Unmarshal(msg, pkt)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
switch pkt.GetTyp() {
|
||||
case ServerPacketType_PING:
|
||||
serverProxyLastHB = time.Now()
|
||||
resp := &ServerPacket{
|
||||
Typ: ServerPacketType_PONG,
|
||||
}
|
||||
pkt := &ServerPacket{}
|
||||
err := proto.Unmarshal(msg, pkt)
|
||||
buf, err := proto.Marshal(resp)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
switch pkt.GetTyp() {
|
||||
case ServerPacketType_PING:
|
||||
serverProxyLastHB = time.Now()
|
||||
resp := &ServerPacket{
|
||||
Typ: ServerPacketType_PONG,
|
||||
}
|
||||
buf, err := proto.Marshal(resp)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
conn.WriteChan <- ws.Binary(buf)
|
||||
}
|
||||
conn.WriteChan <- ws.Binary(buf)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -312,7 +370,7 @@ var serverUpgrader = websocket.Upgrader{
|
||||
}
|
||||
|
||||
func generateServerId(prefix string) string {
|
||||
return string(prefix) + util.RandStringNumber(rand.Intn(2)+1) + strings.ToUpper(util.RandStringAlphabet(rand.Intn(2)+1))
|
||||
return prefix + util.RandStringNumber(rand.Intn(2)+1) + strings.ToUpper(util.RandStringAlphabet(rand.Intn(2)+1))
|
||||
}
|
||||
|
||||
var serverHBTicker = time.NewTicker(time.Second * 5)
|
||||
|
Reference in New Issue
Block a user