因為我這邊要做對戰(zhàn)游戲幀同步的服務器,使用了定時器做事件幀同步。
之前使用的方案是房主發(fā)起開啟幀同步的事件,然后 BusinessWorker 開啟毫秒定時器并將itmer_id記錄erdis。
后來突然想到,如果房主掉線再恢復,導致redis記錄的timer_id可能會失效(比如重連的時候 gateway 轉(zhuǎn)發(fā)消息不再轉(zhuǎn)發(fā)到上次在線時綁定的進程)最終導致無法停止幀同步時間。
然后我就想到使用channel,組件來隔離用戶主動發(fā)起幀同步的事件,轉(zhuǎn)由另一個worker來啟動,這樣可以保證不管是BusinessWorker重啟也好,客戶端斷線重連也好,都不會影響到正在運行的定時器。
我在github上看到channel組件(https://github.com/walkor/Channel 支持2種消息發(fā)送模式發(fā)布訂閱的事件機制和消息隊列機制。
我打算使用消息隊列機制開啟一組獨立的進程專門監(jiān)聽幀同步的業(yè)務(開啟,停止毫秒定時器并轉(zhuǎn)發(fā)幀數(shù)據(jù))。因為我只需要一組進程有一個接收到事件并開始執(zhí)行邏輯即可,不需要訂閱模式(訂閱模式每個進程都會收到消息并處理,這并不是我想要的)。
消息隊列示例
use Workerman\Worker;
use Workerman\Timer;
$worker = new Worker();
$worker->name = 'Producer';
$worker->onWorkerStart = function()
{
Client::connect();
$count = 0;
Timer::add(1, function() {
Client::enqueue('queue', 'Hello World '.time());
});
};
$mq = new Worker();
$mq->name = 'Consumer';
$mq->count = 4;
$mq->onWorkerStart = function($worker) {
Client::connect();
//訂閱消息 queue
Client::watch('queue', function($data) use ($worker) {
echo "Worker {$worker->id} get queue: $data\n";
});
//10 秒后取消訂閱該消息
Timer::add(10, function() {
Client::unwatch('queue');
}, [], false);
};
Worker::runAll();
這段代碼是我在github 頁面上看到的,但是我在require 組建后,并沒有看到客戶端有 watch 相關(guān)的代碼,請問是什么原因?
或者有沒有什么其他推薦方案我可以采用
謝謝作者