* @copyright walkor * @link http://www.workerman.net/ * @license http://www.opensource.org/licenses/mit-license.php MIT License */ /** * 用于检测业务代码死循环或者长时间阻塞等问题 * 如果发现业务卡死,可以将下面declare打开(去掉//注释),并执行php start.php reload * 然后观察一段时间workerman.log看是否有process_timeout异常 */ declare(ticks=1); use \GatewayWorker\Lib\Gateway; use Workerman\Lib\Timer; //defined('IN_WEB') or define('IN_WEB', true); define('WORKERNAME', 'Service'); //define('WWWROOT', dirname(__FILE__).'/../../'); //require_once WWWROOT . 'core.php'; //define( 'PATH_CFG', WWWROOT . 'config/'.$config['sidlist'][1].$isTset.'/'); //require_once PATH_CFG . 'config.inc.php'; //oo::setConfig( $config); //设置全局变量 //oo::functions()->header(); /** * 主逻辑 * 主要是处理 onConnect onMessage onClose 三个方法 * onConnect 和 onClose 如果不需要可以不用实现并删除 */ class Events { public static function onWorkerStart($worker){ global $dbs; global $rediss; $dbs = oo::commonOprDb('common'); $dbs->connect(); $redisArr =['common','statistics']; foreach ($redisArr as $v){ $rediss[$v] = oo::commonOprRedis($v); } $time_id = Timer::add(5, function () use (&$time_id,$redisArr) { global $dbs; global $rediss; if(!$dbs->ping()){//失败释放内存,重连 echo date('Y-m-d H:i:s').'close-mysql'."\r\n"; $dbs->close(); oo::$objDb =[]; $dbs = oo::commonOprDb('common'); } foreach ($redisArr as $v){ if(!$rediss[$v]->ping()){//失败释放内存,重连 echo date('Y-m-d H:i:s').'close-redis'."\r\n"; $rediss[$v]->close(); oo::$objRedis =[]; $rediss[$v] = oo::commonOprRedis('common'); } } }); //保存各自节点所有在线玩家信息 $recordTimer = Timer::add(30, function () { //每30秒存储一次all uid到redis if(!oo::commonOprModel('workerman')->checkNeedSave()){ return; } oo::commonOprModel('workerman')->saveAllUids(Gateway::getAllUidList()); }); //订阅各自节点的消息 Timer::add(2, function () { $lastSubPush = time(); oo::commonOprModel('workerman')->pushMsgSubscribe(); }); } /** * 当客户端连接时触发 * 如果业务不需此回调可以删除onConnect * * @param int $client_id 连接id */ public static function onConnect($client_id){ $time_id = Timer::add(5, function () use ($client_id , &$time_id) { if(empty(Gateway::getSession($client_id))){ Gateway::closeClient($client_id); } Timer::del($time_id); }); } /** * 当客户端发来消息时触发 * @param int $client_id 连接id * @param mixed $message 具体消息 */ public static function onMessage($client_id, $message){ json_decode($message); if(json_last_error() == JSON_ERROR_NONE){ $res =json_decode($message,true); $res['encryp'] = 0; }else{ $res = ProtocolsEvent::wsDecode($message); $res['encryp'] = 1; } if($res['cmd'] == 0x2008){ list($t1, $t2) = explode(' ', microtime()); $mSeconds = (float)sprintf('%.0f', (floatval($t1) + floatval($t2)) * 1000); $str = json_encode(['cmd'=>0x600d,'code'=>1,"ts"=>time(), 'm_ts' => $mSeconds]); if($res['encryp']){ $str = ProtocolsEvent::encode($str); } Gateway::sendToClient($client_id, $str); $uid = Gateway::getUidByClientId($client_id); $uid && oo::commonOprModel('workerman')->online($uid); return; } if(in_array($res['cmd'],array_keys(ocmd::$Cmd))){ $res['cmd'] = ocmd::$Cmd[$res['cmd']]; $session = Gateway::getSession($client_id); if(!isset($res['uid'])){ if(isset($session[$client_id]['uid'])){ $res['uid'] = intval($session[$client_id]['uid']); } } //每10次请求更新一次在线标记 if(!empty($res['uid'])){ $incrRet = oo::commonOprRedis('user')->incr(okeys::userWsReq($res['uid'])); if($incrRet && $incrRet == 1){ //60秒过期 oo::commonOprRedis('user')->expire(okeys::userWsReq($res['uid']), 60); } if($incrRet && $incrRet % 11 == 0){ //更新在线标记 oo::commonOprRedis('user')->delete(okeys::userWsReq($res['uid'])); oo::commonOprModel('workerman')->online($res['uid']); } } $action = explode('_',$res['cmd']); self::CrazyGodEvents(ucfirst($action[0]),ucfirst($action[1]),$client_id,$res); } } /** * 当用户断开连接时触发 * @param int $client_id 连接id */ public static function onClose($client_id){ self::CrazyGodEvents('User','Offline',$client_id); } /** * 选择业务类 * @param $mod * @param $func * @param $client_id * @param mixed $data */ public static function CrazyGodEvents($mod,$func, $client_id, $data = ''){ require_once __DIR__ . '/../Function/' .$mod.'.php'; $mod = $mod.'CrazyWorker'; $obj = new $mod(isset($data['sid'])?$data['sid']:1,$client_id); $obj->$func($client_id,$data); } }