/** * 注册一个新服务器 * * @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(); }