一個人做游戲,服務器的開發也就成了必然的事情
選擇服務器框架Skynet
選擇skynet的原因不僅僅是因為雲風是我的偶像,也有一下幾個原因
- 輕量級,會lua就可以開發游戲邏輯
- 有成熟的項目先例
- 性能高效,可分布式
配置開發環境
本人用mac開發,windows建議安裝Linux虛擬機進行開發
配置 Skynet
- clone Skynet下來,進入目錄,運行
make macosx
命令
配置 Mysql
下載Mysql
$ brew install mysql
啟動Mysql
$ brew services start mysql
$ mysql_secure_installation
按照提示設置用戶和密碼繼續
$ mysql -uroot -p
輸入密碼后成功鏈接mysql
測試
test目錄下有一個testmysql.lua 創建一個‘skynet’ database 並且配置好用戶密碼測試,這時有個鏈接問題
Client does not support authentication protocol requested by server
解決辦法如下:
方案一
USE mysql;
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '831015';
FLUSH PRIVILEGES;
root是用戶名,localhost是ip地址127.0.0.1都是特指本機,mysql_native_password是舊的密碼驗證機制,831015是密碼,最后別忘了分號;
運行testmysql.lua 鏈接成功
方案二
修改mysql配置文件:
[mysqld]
default_authentication_plugin=mysql_native_password
Redis 和 Mysql數據同步方案
整體思路
玩家登錄后讀取Mysql數據緩存到Redis中,邏輯操作再redis中進行,斷線后進行落地
Mysql表設計與必要信息
1. user //id自增的角色信息,用來標識玩家
2. money //主鍵為user id 做游戲,貨幣是必須的
3. snode //記錄服務器信息,包括版本更新迭代信息
4. role //一人多號,id自增
5. item //主鍵為role id
Redis表設計與Mysql映射
redis數據使用hashmap存儲與sql表的關系,以表名
+分隔符
+數據唯一id
作為key來存儲
譬如說這條信息'role':${uid}:${rid}
,其中role
為代表role表,${uid}
代表此玩家uid作為可變參數${rid}
作為此角id可變參數,玩家使用uid與rid作為邏輯參數,服務器查詢redis庫進行查詢驗證操作
實現方式
因為要修改redis表並且將redis中的數據落地到Mysql中,所以要增加必要的格式檢查以免程序操作失誤引起意外
- 服務器啟動時候分析MySQL表結構,將表結構信息緩存在全局常量里
- 修改redis使用剛才分析的表數據統一進行格式驗證
- 落地操作進行日志跟蹤
注意
服務器架構部署方案
使用框架自帶的watchdog服務
+游戲類服務
部署設計思路
watchdog
負責管理連接,從client
開始連接到生成agent
之前的socket data
通信數據,轉發到SignInServer
進行處理,完成后通知watchdog
創建客戶端agent
並保存,agent
是客戶端代理,因為lua虛擬機天然的優秀隔離,用戶自身狀態保存在這里,使用時候取用。所有業務邏輯被agent
轉發處理並回執,agent
收到回執發給客戶端完成整個通信聲明周期
watchdog服務
修改了watchdogsocket data
部分,游戲連接握手使用socket data
進行轉發給SignInServer
(自己實現的注冊服務)
游戲類服務
- IDServer
- SignInServer
- DaoServer
- LogicServer
IDServer
- 全局的
- 可分布式的
- 無狀態
生成guid是門技術,單獨取出維護,方便以后拓展優化,因為精力有限,目前方式是開了一個協程周期(每分鍾)更新隨機種子,使用uuid進行id的生成
SignInServer
- 全局的
- 可分布式的
- 無狀態
路由保存在watchdog
中,每個客戶端連接后分配一個物理SignInServer
服務器(可以本機,取決於自己),處理客戶端連接握手部分,使用狀態機進行狀態驅動,處理客戶端socket連接后數據,設置好超時時間,處理注冊和自動登錄邏輯
DaoServer
- 全局的
- 可分布式的
- 無狀態
負責客戶端上線后的MySql數據拉取到Redis與斷線后Redis的落地到MySql操作
LogicServer
- 全局的
- 可分布式的
- 無狀態
負責游戲邏輯,玩家狀態通過詢問agent
獲取處理,如果是復雜玩法(如多人副本)可以新增一個有狀態服務進行拓展,不過有狀態服務要分布式的話要維護好與agent
的連接關系
結束語
耗時三個月零零散散終於把自己的服務器部分完整了(。・∀・)ノ,已經開始做小游戲了,使用Unity,有完整的熱更流程,有完整的服務器部分,程序只有我自己,光桿司令,確實是比較累的,不過我會堅持的。萬一財富自由了呢
ε=ε=ε=( ̄▽ ̄)
PS:歡迎評論(。^▽^)