Ejemplo n.º 1
0
 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);
         }
     }
 }
Ejemplo n.º 2
0
 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();
 }
Ejemplo n.º 3
0
Archivo: RPC.php Proyecto: myqee/server
 /**
  * 注册一个新服务器
  *
  * @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;
 }
Ejemplo n.º 4
0
 /**
  * 添加一个HOST
  *
  * @param Host $host
  */
 public static function onServerAdd($host)
 {
     Host::$lastChangeTime->set(time());
     $host->save();
 }
Ejemplo n.º 5
0
 /**
  * 获取对象
  *
  * @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];
 }