- 上一章地址:juejin.im/post/5cc1c8…
聯機邏輯開發進度:□□□□□□□□□□□□
本章結束開發進度:■■□□□□□□□□□□
Swoole開發環境
教程使用Swoole 4.3.0
版本開發,但並沒有使用協程等功能,只是使用了WebSocket Server
,理論上安裝舊版也是沒問題的。環境需要大家自行安裝,這個也是學習的一個過程。
以下是一些有可能有幫助的資料:
CentOS
中一鍵安裝PHP
開發環境:lnmp.org/install.htm…Swoole
安裝教程:wiki.swoole.com/wiki/page/6…Redis
安裝教程:redis.io/downloadphp-redis
擴充套件包:pecl.php.net/package/red…
童鞋們也可以像我一樣在Windows
使用PHPStorm
進行開發,再通過一些方法如共享資料夾
、WinSCP
等工具將專案在CentOS
中執行起來。
安裝swoole-ide-helper擴充套件
使用PHPStorm
來開發Swoole
專案的童鞋,如果不想面向運氣程式設計的話,最好安裝一個swoole-ide-Helper
擴充套件來協作開發。
在專案根目錄執行以下命令:
composer require --dev "eaglewu/swoole-ide-helper:dev-master"
複製程式碼
安裝完畢我們就可以愉快地編寫Swoole
程式碼了。
服務端基本架構
趙童鞋設想的基本架構需要三個層,他們分別是:
- 網路層:管理
Swoole WebSocket
物件,主要負責接收前端訊息,傳遞到邏輯層進行處理。 - 邏輯層:接收網路層傳遞的訊息,主要負責遊戲房間建立、玩家移動、結束檢測等遊戲邏輯。
- 資料層:用於管理玩家ID、房間ID、匹配佇列等資料。
管理這三個層分別需要三個類:Server
、Logic
、DataCenter
。
其中最重要的就是Server
類,它的作用就是作為服務端和客戶端的訊息交換中心,我們先來寫一個初始化的Server
類,在專案app
目錄新建Server.php
。
- 使用物件導向的方式實現一個
WebSocket Server
類。 - 分別繫結
start
、workerStart
、open
、message
、close
回撥方法 - 在類中引入
composer
自動載入機制。 - 為
WebSocket
物件設定4個worker
程式。
Swoole Websocket
:wiki.swoole.com/wiki/page/3…
Server
類:
<?php
require_once __DIR__ . '/../vendor/autoload.php';
class Server
{
const HOST = '0.0.0.0';
const PORT = 8811;
const CONFIG = [
'worker_num' => 4,
];
private $ws;
public function __construct()
{
$this->ws = new \Swoole\WebSocket\Server(self::HOST, self::PORT);
$this->ws->set(self::CONFIG);
$this->ws->on('start', [$this, 'onStart']);
$this->ws->on('workerStart', [$this, 'onWorkerStart']);
$this->ws->on('open', [$this, 'onOpen']);
$this->ws->on('message', [$this, 'onMessage']);
$this->ws->on('close', [$this, 'onClose']);
$this->ws->start();
}
public function onStart($server)
{
swoole_set_process_name('hide-and-seek');
echo sprintf("master start (listening on %s:%d)\n",
self::HOST, self::PORT);
}
public function onWorkerStart($server, $workerId)
{
echo "server: onWorkStart,worker_id:{$server->worker_id}\n";
}
public function onOpen($server, $request)
{
}
public function onClose($server, $fd)
{
}
public function onMessage($server, $request)
{
}
}
new Server();
複製程式碼
我們來執行一下Server.php
檔案,順便檢驗一下Swoole
擴充套件是否執行正常,在專案app
目錄下,執行php Server
。
- 後面所有啟動
Server
操作都是基於CentOS
環境
[root@localhost app]# php Server.php
master start (listening on 0.0.0.0:8811)
server: onWorkStart,worker_id:0
server: onWorkStart,worker_id:1
server: onWorkStart,worker_id:2
server: onWorkStart,worker_id:3
複製程式碼
如果輸出以上資訊,就代表Server
執行成功。
Logic
類和DataCenter
類屬於遊戲管理類,在Manager
資料夾下新建Logic.php
和DataCenter.php
檔案,並在Datacenter
類中增加一個格式化輸出日誌的log()
方法。
Logic
類:
<?php
namespace App\Manager;
class Logic
{
}
複製程式碼
DataCenter
類:
<?php
namespace App\Manager;
class DataCenter
{
public static function log($info, $context = [], $level = 'INFO')
{
if ($context) {
echo sprintf("[%s][%s]: %s %s\n", date('Y-m-d H:i:s'), $level, $info,
json_encode($context, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE));
} else {
echo sprintf("[%s][%s]: %s\n", date('Y-m-d H:i:s'), $level, $info);
}
}
}
複製程式碼
前端初始化
前端我們將會使用Vue
框架來開發,專案只使用到了v-if
、v-for
、<template>
、WebSocket
技術。如果沒有接觸過前端框架的童鞋,可以嘗試閱讀官方文件。
Vue
官方文件:cn.vuejs.org/v2/guide/v-if
:cn.vuejs.org/v2/guide/co…v-for
:cn.vuejs.org/v2/guide/li…<templater>
:cn.vuejs.org/v2/guide/li…
在專案根目錄建立frontend
資料夾,並在其中建立index.html
檔案,進行前端初始化。
- 使用
CDN
的形式引入Vue
框架。 - 根據
Vue
官方文件,編寫一個HelloWorld
頁面。
index.html
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>HideAndSeek</title>
<script src="https://cdn.bootcss.com/vue/2.6.10/vue.js"></script>
<link rel="icon" href="data:;base64,=">
</head>
<body>
<div id="app">
{{ message }}
</div>
<script>
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
</script>
</body>
</html>
複製程式碼
前端的HelloWorld
頁面我們也有了,但是我們要怎麼通過HTTP
請求獲取到這個頁面呢?這時候就需要使用Swoole
的Static Handler
功能。
Swoole Static Handler
文件:wiki.swoole.com/wiki/page/7…
- 根據官方文件新增
Swoole Static Handler
配置。 - 為
Server
新增一個監聽埠8812
,用於處理HTTP請求。
Server
類:
const FRONT_PORT = 8812;
const CONFIG = [
...
'enable_static_handler' => true,
'document_root' =>
'/mnt/htdocs/HideAndSeek_teach/frontend',
];
public function __construct()
{
...
$this->ws->listen(self::HOST, self::FRONT_PORT, SWOOLE_SOCK_TCP);
...
}
複製程式碼
記得將程式碼中的document_root
改為自己專案的前端目錄哦。
新增完以上程式碼後,在虛擬機器中執行Server
,並嘗試通過瀏覽器訪問http://虛擬機器ip:8812/index.html
瀏覽前端頁面。
WebSocket初始化
現在專案的服務端有了,前端頁面有了,就差一個橋樑把他們連線起來,這個橋樑就是WebSocket
通訊機制,專案使用到了簡單的websock.onmessage
、websock.onopen
、websock.onerror
、websock.onclose
。
以下是一些有可能有幫助的資料。
- 阮一峰
WebSocket
教程:www.ruanyifeng.com/blog/2017/0… Vue
生命週期:cn.vuejs.org/v2/guide/in…Swoole WebSocket onMessage
wiki.swoole.com/wiki/page/4…
- 為
Vue
例項新增data
屬性websock
,在Vue
例項建立完畢後,初始化WebSocket
連線服務端並繫結上述四個方法。 - 在
WebSocket
物件建立連線後,立刻傳送訊息到服務端。 - 服務端接收到客戶端傳送的訊息後,通過客戶端的
fd
返回一條訊息。 - 服務端增加客戶端連線日誌輸出。
- 在頁面關閉時,斷開
WebSocket
連線。
- 不清楚
fd
是什麼的童鞋可以參考Swoole
官方文件:wiki.swoole.com/wiki/page/5…
本章專案初始化就到這裡啦,請童鞋們儘量完成自己的Homework後,再進入下一章的學習。
當前專案結構:
HideAndSeek
├── app
│ ├── Manager
│ │ ├── DataCenter.php
│ │ ├── Game.php
│ │ └── Logic.php
│ ├── Model
│ │ ├── Map.php
│ │ └── Player.php
│ └── Server.php
├── composer.json
├── composer.lock
├── frontend
│ └── index.html
├── test.php
└── vendor
├── autoload.php
└── composer
複製程式碼