test: 移除 examples 包

This commit is contained in:
kercylan98 2023-07-07 15:11:01 +08:00
parent 8b903072b1
commit f0e3822ecf
10 changed files with 1 additions and 271 deletions

View File

@ -3,6 +3,7 @@
[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/kercylan98/minotaur)
![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat)
![](https://komarev.com/ghpvc/?username=kercylan98)
<a target="_blank" href="https://goreportcard.com/report/github.com/kercylan98/minotaur"><img src="https://goreportcard.com/badge/github.com/kercylan98/minotaur?style=flat-square" /></a>
Minotaur 是一个基于Golang 1.20 编写的服务端开发支持库,其中采用了大量泛型设计,用于游戏服务器开发。
@ -39,7 +40,6 @@ $ go get -u github.com/kercylan98/minotaur
## 用法
- 在`Minotaur`中大量使用了 **[泛型](https://go.dev/doc/tutorial/generics)** 、 **[观察者(事件)](https://www.runoob.com/design-pattern/observer-pattern.html)** 和 **[选项模式](https://juejin.cn/post/6844903729313873927)**,在使用前建议先进行相应了解;
- 更多的 **[示例](./examples)** 参考可在 [examples](./examples) 目录查阅;
- 项目文档可访问 **[pkg.go.dev](https://pkg.go.dev/github.com/kercylan98/minotaur)** 进行查阅;
### 本地文档

View File

@ -1,2 +0,0 @@
// Package examples 提供了多种实现案例
package examples

View File

@ -1,96 +0,0 @@
// 该案例中将服务器消息通过多核的方式异步传输到房间中,在每个房间中单独同步处理维护消息。
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)
}
}

View File

@ -1,36 +0,0 @@
// 该案例实现了一个简单的聊天室功能
package main
import (
"fmt"
"github.com/kercylan98/minotaur/server"
"github.com/kercylan98/minotaur/utils/synchronization"
)
func main() {
connections := synchronization.NewMap[string, *server.Conn]()
srv := server.New(server.NetworkWebsocket, server.WithWebsocketWriteMessageType(server.WebsocketMessageTypeText))
srv.RegConnectionOpenedEvent(func(srv *server.Server, conn *server.Conn) {
for _, c := range connections.Map() {
c.Write([]byte(fmt.Sprintf("%s 加入了聊天室", conn.GetID())))
}
connections.Set(conn.GetID(), conn)
conn.Write([]byte("欢迎加入"))
})
srv.RegConnectionClosedEvent(func(srv *server.Server, conn *server.Conn, err any) {
if connections.DeleteExist(conn.GetID()) {
for id, c := range connections.Map() {
c.Write([]byte(fmt.Sprintf("%s 退出了聊天室", id)))
}
}
})
srv.RegConnectionReceiveWebsocketPacketEvent(func(srv *server.Server, conn *server.Conn, packet []byte, messageType int) {
for _, c := range connections.Map() {
c.Write([]byte(fmt.Sprintf("%s: %s", conn.GetID(), string(packet))))
}
})
if err := srv.Run(":9999"); err != nil {
panic(err)
}
}

View File

@ -1,18 +0,0 @@
// 该案例中延时了控制台服务器的实现,支持运行中根据控制台指令执行额外的功能逻辑
package main
import (
"github.com/kercylan98/minotaur/server"
"github.com/kercylan98/minotaur/utils/log"
"go.uber.org/zap"
)
func main() {
srv := server.New(server.NetworkWebsocket)
srv.RegConsoleCommandEvent("test", func(srv *server.Server) {
log.Info("Console", zap.String("Info", "Test"))
})
if err := srv.Run(":9999"); err != nil {
panic(err)
}
}

View File

@ -1,25 +0,0 @@
package main
import (
"github.com/kercylan98/minotaur/server"
"github.com/kercylan98/minotaur/server/cross"
"github.com/kercylan98/minotaur/utils/log"
"github.com/kercylan98/minotaur/utils/timer"
"go.uber.org/zap"
"time"
)
func main() {
srv := server.New(server.NetworkWebsocket, server.WithCross("nats", 1, cross.NewNats("127.0.0.1:4222")), server.WithTicker(10, false))
srv.RegStartFinishEvent(func(srv *server.Server) {
srv.Ticker().Loop("CROSS", timer.Instantly, time.Second, timer.Forever, func() {
server.PushCrossMessage(srv, "nats", 2, []byte("I am cross 1"))
})
})
srv.RegReceiveCrossPacketEvent(func(srv *server.Server, senderServerId int64, packet []byte) {
log.Info("Cross", zap.Int64("ServerID", senderServerId), zap.String("Packet", string(packet)))
})
if err := srv.Run(":9999"); err != nil {
panic(err)
}
}

View File

@ -1,25 +0,0 @@
package main
import (
"github.com/kercylan98/minotaur/server"
"github.com/kercylan98/minotaur/server/cross"
"github.com/kercylan98/minotaur/utils/log"
"github.com/kercylan98/minotaur/utils/timer"
"go.uber.org/zap"
"time"
)
func main() {
srv := server.New(server.NetworkWebsocket, server.WithCross("nats", 2, cross.NewNats("127.0.0.1:4222")), server.WithTicker(10, false))
srv.RegStartFinishEvent(func(srv *server.Server) {
srv.Ticker().Loop("CROSS", timer.Instantly, time.Second, timer.Forever, func() {
server.PushCrossMessage(srv, "nats", 1, []byte("I am cross 2"))
})
})
srv.RegReceiveCrossPacketEvent(func(srv *server.Server, senderServerId int64, packet []byte) {
log.Info("Cross", zap.Int64("ServerID", senderServerId), zap.String("Packet", string(packet)))
})
if err := srv.Run(":19999"); err != nil {
panic(err)
}
}

View File

@ -1,2 +0,0 @@
// 该案例中演示了两个跨服相互通过网络进行数据传输的实现
package main

View File

@ -1,16 +0,0 @@
// 该案例中实现了一个简单的回响服务器
package main
import (
"github.com/kercylan98/minotaur/server"
)
func main() {
srv := server.New(server.NetworkWebsocket)
srv.RegConnectionReceiveWebsocketPacketEvent(func(srv *server.Server, conn *server.Conn, packet []byte, messageType int) {
conn.Write(packet, messageType)
})
if err := srv.Run(":9999"); err != nil {
panic(err)
}
}

View File

@ -1,50 +0,0 @@
package main
import (
"github.com/kercylan98/minotaur/component/components"
"github.com/kercylan98/minotaur/game/builtin"
"github.com/kercylan98/minotaur/server"
"github.com/kercylan98/minotaur/utils/synchronization"
)
type Player struct {
*builtin.Player[string]
}
type Command struct {
CMD int
Data string
}
// 访问http://www.websocket-test.com/
// - 使用多个页面连接到服务器后任一页面发送start即可开启帧同步
func main() {
players := synchronization.NewMap[string, *Player]()
srv := server.New(server.NetworkWebsocket, server.WithWebsocketWriteMessageType(server.WebsocketMessageTypeText))
lockstep := components.NewLockstep[string, *Command]()
srv.RegConnectionOpenedEvent(func(srv *server.Server, conn *server.Conn) {
player := &Player{Player: builtin.NewPlayer[string](conn.GetID(), conn)}
players.Set(conn.GetID(), player)
lockstep.JoinClient(player)
})
srv.RegConnectionClosedEvent(func(srv *server.Server, conn *server.Conn, err any) {
players.Delete(conn.GetID())
lockstep.LeaveClient(conn.GetID())
if players.Size() == 0 {
lockstep.StopBroadcast()
}
})
srv.RegConnectionReceiveWebsocketPacketEvent(func(srv *server.Server, conn *server.Conn, packet []byte, messageType int) {
switch string(packet) {
case "start":
lockstep.StartBroadcast()
default:
lockstep.AddCommand(&Command{CMD: 1, Data: string(packet)})
}
})
if err := srv.Run(":9999"); err != nil {
panic(err)
}
}