From 12457f3631c386fdd390da2d95c416f6040b0c6e Mon Sep 17 00:00:00 2001 From: kercylan98 Date: Sat, 20 May 2023 15:20:31 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=A5=E6=88=BF=E9=97=B4=E4=B8=BA=E6=A0=B8?= =?UTF-8?q?=E5=BF=83=E7=8E=A9=E6=B3=95=E7=9A=84=E5=A4=9A=E6=A0=B8=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E5=99=A8=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/multi-core-server-room-sync/main.go | 95 ++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 examples/multi-core-server-room-sync/main.go diff --git a/examples/multi-core-server-room-sync/main.go b/examples/multi-core-server-room-sync/main.go new file mode 100644 index 0000000..7bddba3 --- /dev/null +++ b/examples/multi-core-server-room-sync/main.go @@ -0,0 +1,95 @@ +package main + +import ( + "fmt" + "github.com/kercylan98/minotaur/game/builtin" + "github.com/kercylan98/minotaur/server" + "github.com/kercylan98/minotaur/utils/synchronization" + "strconv" + "strings" +) + +type message struct { + conn *server.Conn + packet []byte +} + +type Room struct { + *builtin.Room[string, *builtin.Player[string]] + channel chan *message // need close + pool *synchronization.Pool[*message] +} + +func newRoom(guid int64) *Room { + room := &Room{ + Room: builtin.NewRoom[string, *builtin.Player[string]](guid), + } + room.pool = synchronization.NewPool[*message](1024*100, func() *message { + return new(message) + }, func(data *message) { + data.conn = nil + data.packet = nil + }) + room.channel = make(chan *message, 1024*100) + go func() { + for msg := range room.channel { + room.handePacket(msg.conn, msg.packet) + room.pool.Release(msg) + } + }() + return room +} + +func (slf *Room) PushMessage(conn *server.Conn, packet []byte) { + msg := slf.pool.Get() + msg.conn = conn + msg.packet = packet + slf.channel <- msg +} + +func (slf *Room) handePacket(conn *server.Conn, packet []byte) { + conn.WriteString(fmt.Sprintf("[%d] %s", slf.GetGuid(), string(packet))) +} + +// 以房间为核心玩法的多核服务器实现 +// - 服务器消息处理为异步执行 +// - 由房间分发具体消息,在房间内所有消息为同步执行 +func main() { + rooms := synchronization.NewMap[int64, *Room]() + + srv := server.New(server.NetworkWebsocket, + server.WithWebsocketWriteMessageType(server.WebsocketMessageTypeText), + server.WithMultiCore(10), + ) + + srv.RegConnectionReceiveWebsocketPacketEvent(func(srv *server.Server, conn *server.Conn, packet []byte, messageType int) { + p := strings.SplitN(string(packet), ":", 2) + roomId, err := strconv.ParseInt(p[0], 10, 64) + if err != nil { + conn.WriteString(fmt.Sprintf("wrong room id, err: %s", err.Error())) + return + } + // 假定命令格式 ${房间ID}:命令 + switch p[1] { + case "create": + if !rooms.Exist(roomId) { + rooms.Set(roomId, newRoom(roomId)) + conn.WriteString(fmt.Sprintf("create room[%d] success", roomId)) + } else { + conn.WriteString(fmt.Sprintf("room[%d] existed", roomId)) + } + default: + room, exist := rooms.GetExist(roomId) + if !exist { + rooms.Set(roomId, room) + conn.WriteString(fmt.Sprintf("room[%d] does not exist, create room please use ${roomId}:create", roomId)) + } else { + room.PushMessage(conn, []byte(p[1])) + } + } + }) + + if err := srv.Run(":9999"); err != nil { + panic(err) + } +}