定时器覆盖问题

0

public function onMessage($connection, $data)
{
global $worker;
$connection->lastMessageTime = time();
$data = json_decode($data, true);
$_SESSION['hotel_price'] = '';
switch($data['type']){
case 'login':
$where['id'] = $data['id'];
$where['token'] = $data['token'];
$id = Db::name('business')->where($where)->value('id');
if($id){
$connection->uid = $id;//设置当前客户端id
$worker->uidConnections[$connection->uid] = $connection;//保存到服务器里
$connection->send('{"type":"login","msg":"登录成功"}');
$timer = new Timer();
$connection->timer_id = $timer->add('10',function()use($connection,$data){
$connection->send('{"type":"ping"}');
});
}else{
$connection->timer_id = '';
$connection->uid = $data['id'].$data['token'];
$worker->uidConnections[$connection->uid] = $connection;//保存到服务器里
$connection->send('{"type":"login","msg":"登录失败"}');
$connection->close();
}
break;
}
}


如果用户多点了一次login的话 定时器就会形成两个ping到客户端了 各位大神 怎么解决?

已邀请:

taozywu - http://www.athanb.com

赞同来自:

首先你需要多看下文档,定时器不建议写在onMessage回调。


从你代码中大致得出定时器主要做一件事:那就是心跳检测。


如下为大概示例:


<?php
 
require_once __DIR__ . '/Workerman/Autoloader.php';
 
 
use Workerman\Worker;
use Workerman\Lib\Timer;

$worker = new Worker('tcp://0.0.0.0:1234');

$worker->onWorkerStart = function($worker) {
// 防止开多进程
if ($worker->id === 0) {
Timer::add(10, function()use($worker) {
foreach($worker->connections as $connection) {
$connection->send('{"type":"ping"}');
}
});
}
};
 
$worker->onConnect = function($connection) {
};

$worker->onMessage = function($connection, $data) {
global $worker;
$connection->lastMessageTime = time();
$data = json_decode($data, true);
$_SESSION['hotel_price'] = '';
switch ($data['type']) {
case 'login':
$where['id'] = $data['id'];
$where['token'] = $data['token'];
$id = Db::name('business')->where($where)->value('id');
if ($id) {
$connection->uid = $id; //设置当前客户端id
$worker->uidConnections[$connection->uid] = $connection; //保存到服务器里
$connection->send('{"type":"login","msg":"登录成功"}');
} else {
$connection->timer_id = '';
$connection->uid = $data['id'] . $data['token'];
$worker->uidConnections[$connection->uid] = $connection; //保存到服务器里
$connection->send('{"type":"login","msg":"登录失败"}');
$connection->close();
}
break;
}
};

// 如果不是在根目录启动,则运行runAll方法
if(!defined('GLOBAL_START')) {
Worker::runAll();
}

要回复问题请先登录注册