public function onClose($server, $fd, $fromId) { $host = Host::getHostByFd($fd); if ($host) { # 已经有连接上的服务器 Server::$instance->info("host#{$host->group}.{$host->id}({$host->ip}:{$host->port}) close connection."); $host->remove(); # 移除服务 foreach (Host::$table as $item) { if ($item['group'] === $host->group && $item['id'] === $host->id || $item['removed']) { continue; } # 通知所有客户端移除 RPC::factory($item['fd'], $item['from_id'])->trigger('server.remove', $host->group, $host->id); } } }
public function start($ip, $port) { if (!Host::$table) { # Host还没初始化, 需要初始化 Host::init(false); } # 初始化任务服务器 $server = new \Swoole\Server($ip, $port, SWOOLE_BASE, SWOOLE_SOCK_TCP); Server::$server = $server; $this->server = $server; $config = ['dispatch_mode' => 5, 'worker_num' => Server::$config['swoole']['task_worker_num'], 'max_request' => Server::$config['swoole']['task_max_request'], 'task_worker_num' => 0, 'package_max_length' => 1024 * 1024 * 50, 'task_tmpdir' => Server::$config['swoole']['task_tmpdir'], 'buffer_output_size' => Server::$config['swoole']['buffer_output_size'], 'open_eof_check' => true, 'open_eof_split' => true, 'package_eof' => \MyQEE\Server\RPC\Server::$EOF]; $server->set($config); $server->on('WorkerStart', [$this, 'onStart']); $server->on('Receive', [$this, 'onReceive']); $server->on('Start', function () use($ip, $port) { Server::$instance->info("task sever tcp://{$ip}:{$port} start success."); }); $server->start(); }
/** * 注册一个新服务器 * * @param Host $host * @return bool|\stdClass */ public function reg(Host $host) { if (!$host->port) { $this->closeClient('host miss port'); return false; } if (!$host->group) { $host->group = 'default'; } # 获取连接信息 $connection = $this->connectionInfo(); # 没有获取到连接信息 if (!$connection) { return false; } if (!$host->ip) { # 没设置则根据连接时的IP来设置 $host->ip = $connection['remote_ip']; } if (is_numeric($host->id) && $host->id >= 0) { $hostId = (int) $host->id; if (($old = Host::get($hostId, $host->group)) && !$old->removed) { # 指定的服务器ID已经存在, 则不让注册 $this->closeClient('already exists'); Server::$instance->debug("register server error, server {$hostId} already exists."); return false; } } else { # 自动分配ID $hostId = false; # 在移除的服务器列表中找 foreach (Host::$table as $k => $v) { if ($v['removed']) { if ($v['ip'] === $host->ip && $v['port'] == $host->port) { $hostId = $v['id']; break; } } } if (false === $hostId && false === ($hostId = Host::getNewHostId($host->group))) { $this->closeClient('can not assignment id'); return false; } } # 更新服务器ID $host->id = $hostId; $host->key = $host->encrypt ? self::random(32) : ''; $host->fd = $connection['fd']; $host->fromId = $connection['from_id']; # 返回参数 $rs = new \stdClass(); $rs->id = $hostId; // 唯一ID $rs->key = $host->key; // 通讯密钥 $rs->ip = $host->ip; // IP $rs->hosts = Host::getAll(); // 已经连上的服务器列表 # 保存数据 $host->save(); Host::$fdToIdTable->set($host->fd, ['id' => $host->id, 'group' => $host->group]); # 返回一个高级对象 $rpcRs = new Result(); $rpcRs->data = $rs; $rpcRs->on('success', function () use($host) { Server::$instance->info("register a new host#{$host->id}: {$host->ip}:{$host->port}"); $class = get_class($this); # 通知所有 RPC 客户端增加服务器 foreach (Host::$table as $item) { # 已被标志为移除的 if ($item['removed'] > 0) { continue; } # 刚刚添加的不需要通知 if ($item['group'] === $host->group && $item['id'] === $host->id) { continue; } $rpc = new $class($item['fd'], $item['from_id']); /** * @var RPC $rpc */ $rpc->trigger('server.add', $host); } }); return $rpcRs; }
/** * 添加一个HOST * * @param Host $host */ public static function onServerAdd($host) { Host::$lastChangeTime->set(time()); $host->save(); }
/** * 获取对象 * * @param $serverId * @param $workerId * @return Client|false */ public static function getClient($serverGroup, $serverId, $workerId, $isTask = false) { if (!$serverGroup) { # 服务器分组 $serverGroup = Server::$config['clusters']['group'] ?: 'default'; } if ($isTask) { $serverGroup .= '.task'; } if (-1 === $serverId) { # 随机服务器ID $host = Host::getRandHostData($serverGroup); if ($host) { $serverId = $host['id']; } } else { # 随机ID $host = Host::$table->get("{$serverGroup}_{$serverId}"); } if (!$host) { return false; } if (-1 === $workerId) { $workerId = mt_rand(0, $host['worker_num'] - 1); } # 生成一个KEY $key = "{$serverGroup}_{$serverId}_{$workerId}"; if (!isset(self::$instances[$key])) { if (!isset($host)) { $host = Host::$table->get($serverId); if (!$host) { return false; } } # 检查任务ID是否超出序号返回 if ($workerId - $host['worker_num'] > 1) { return false; } /** * @var Client $client */ $class = static::class; $client = new $class(); $client->serverId = $serverId; $client->workerId = $workerId; $client->key = $host['key']; $client->ip = $host['ip']; $client->port = $host['port']; $rs = $client->connect(); if (!$rs) { # 没有连接上去 return false; } self::$instances[$key] = $client; } return self::$instances[$key]; }