Пример #1
0
 /**
  * 从存储中删除删除连不上的gateway通讯端口
  * @param string $addr
  * @param string $errstr
  */
 public function tryToDeleteGatewayAddress($addr, $errstr)
 {
     $key = 'GLOBAL_GATEWAY_ADDRESS';
     if (!isset($this->_badGatewayAddress[$addr])) {
         $this->_badGatewayAddress[$addr] = 0;
     }
     // 删除连不上的端口
     if ($this->_badGatewayAddress[$addr]++ > self::MAX_RETRY_COUNT) {
         Lock::get();
         $addresses_list = Store::instance('gateway')->get($key);
         unset($addresses_list[$addr]);
         Store::instance('gateway')->set($key, $addresses_list);
         Lock::release();
         $this->log("tcp://{$addr} " . $errstr . " del {$addr} from store", false);
     }
 }
Пример #2
0
 /**
  * 删除当前Gateway的内部通信地址
  * @param string $address
  * @return bool
  */
 protected function unregisterAddress()
 {
     $address = $this->lanIp . ':' . $this->lanPort;
     $key = 'GLOBAL_GATEWAY_ADDRESS';
     try {
         $store = Store::instance('gateway');
     } catch (\Exception $msg) {
         $this->log($msg);
         return false;
     }
     // 为保证原子性,需要加锁
     Lock::get();
     $addresses_list = $store->get($key);
     if (empty($addresses_list)) {
         $addresses_list = array();
     }
     unset($addresses_list[$address]);
     if (!$store->set($key, $addresses_list)) {
         Lock::release();
         $msg = "unregisterAddress fail";
         if (get_class($store) == 'Memcached') {
             $msg .= " reason:" . $store->getResultMessage();
         }
         $this->log($msg);
         return;
     }
     Lock::release();
     return true;
 }
Пример #3
0
 /**
  * @param $config_name
  * @return mixed
  * @throws Exception
  */
 protected function getStore($config_name)
 {
     return Store::instance($config_name, $this->getStoreConfig());
 }
Пример #4
0
 /**
  * @param $config_name
  * @return mixed
  * @throws Exception
  */
 protected static function getStore($config_name)
 {
     return Store::instance($config_name, self::$store_config);
 }
Пример #5
0
 /**
  * 添加到客户端列表中
  * @param int $client_id
  * @param string $client_name
  */
 public static function addClientToRoom($room_id, $client_id, $client_name)
 {
     $key = "ROOM_CLIENT_LIST-{$room_id}";
     $store = Store::instance('room');
     // 获取所有所有房间的实际在线客户端列表,以便将存储中不在线用户删除
     $all_online_client_id = Gateway::getOnlineStatus();
     // 存储驱动是memcached
     if (get_class($store) == 'Memcached') {
         $cas = 0;
         $try_count = 3;
         while ($try_count--) {
             $client_list = $store->get($key, null, $cas);
             if (false === $client_list) {
                 if ($store->getResultCode() == \Memcached::RES_NOTFOUND) {
                     $client_list = array();
                 } else {
                     throw new \Exception("Memcached->get({$key}) return false and memcache errcode:" . $store->getResultCode() . " errmsg:" . $store->getResultMessage());
                 }
             }
             if (!isset($client_list[$client_id])) {
                 // 将存储中不在线用户删除
                 if ($all_online_client_id && $client_list) {
                     $all_online_client_id = array_flip($all_online_client_id);
                     $client_list = array_intersect_key($client_list, $all_online_client_id);
                 }
                 // 添加在线客户端
                 $client_list[$client_id] = $client_name;
                 // 原子添加
                 if ($store->getResultCode() == \Memcached::RES_NOTFOUND) {
                     $store->add($key, $client_list);
                 } else {
                     $store->cas($cas, $key, $client_list);
                 }
                 if ($store->getResultCode() == \Memcached::RES_SUCCESS) {
                     return $client_list;
                 }
             } else {
                 return $client_list;
             }
         }
         throw new \Exception("addClientToRoom({$room_id}, {$client_id}, {$client_name})->cas({$cas}, {$key}, \$client_list) fail ." . $store->getResultMessage());
     } else {
         $handler = fopen(__FILE__, 'r');
         flock($handler, LOCK_EX);
         $client_list = $store->get($key);
         if (!isset($client_list[$client_id])) {
             // 将存储中不在线用户删除
             if ($all_online_client_id && $client_list) {
                 $all_online_client_id = array_flip($all_online_client_id);
                 $client_list = array_intersect_key($client_list, $all_online_client_id);
             }
             // 添加在线客户端
             $client_list[$client_id] = $client_name;
             $ret = $store->set($key, $client_list);
             flock($handler, LOCK_UN);
             return $client_list;
         }
         flock($handler, LOCK_UN);
     }
     return $client_list;
 }
Пример #6
0
 /**
  * 想某个用户网关发送命令和消息
  * @param int $client_id
  * @param int $cmd
  * @param string $message
  * @return boolean
  */
 protected static function sendCmdAndMessageToClient($client_id, $cmd, $message)
 {
     // 如果是发给当前用户则直接获取上下文中的地址
     if ($client_id === Context::$client_id || $client_id === null) {
         $address = Context::$local_ip . ':' . Context::$local_port;
     } else {
         $address = Store::instance('gateway')->get('client_id-' . $client_id);
         if (!$address) {
             return false;
         }
     }
     $gateway_data = GatewayProtocol::$empty;
     $gateway_data['cmd'] = $cmd;
     $gateway_data['client_id'] = $client_id ? $client_id : Context::$client_id;
     $gateway_data['body'] = $message;
     return self::sendToGateway($address, $gateway_data);
 }
Пример #7
0
 /**
  * 向所有gateway发送数据
  * @param string $gateway_data
  */
 protected static function sendToAllGateway($gateway_data)
 {
     // 如果有businessWorker实例,说明运行在workerman环境中,通过businessWorker中的长连接发送数据
     if (self::$businessWorker) {
         foreach (self::$businessWorker->gatewayConnections as $gateway_connection) {
             $gateway_connection->send($gateway_data);
         }
     } else {
         $all_addresses = Store::instance('gateway')->get('GLOBAL_GATEWAY_ADDRESS');
         if (!$all_addresses) {
             throw new \Exception('GLOBAL_GATEWAY_ADDRESS is ' . var_export($all_addresses, true));
         }
         foreach ($all_addresses as $address) {
             self::sendToGateway($address, $gateway_data);
         }
     }
 }
Пример #8
0
 /**
  * 删除当前Gateway的内部通信地址
  * @param string $address
  * @return bool
  */
 protected function unregisterAddress()
 {
     $address = $this->lanIp . ':' . $this->lanPort;
     $key = 'GLOBAL_GATEWAY_ADDRESS';
     try {
         $store = Store::instance('gateway');
     } catch (\Exception $msg) {
         $this->log($msg);
         return false;
     }
     // 为保证原子性,需要加锁
     Lock::get();
     if (!$store->hDel($key, $address)) {
         Lock::release();
         $msg = "unregisterAddress fail";
         $this->log($msg);
         return;
     }
     Lock::release();
     return true;
 }
Пример #9
0
 public static function getStoreInstance()
 {
     return Store::instance('gateway');
 }