/** * 定时检查gateway通信端口,如果有新的gateway则去建立长连接 */ public function checkGatewayConnections() { $key = 'GLOBAL_GATEWAY_ADDRESS'; $addresses_list = Store::instance('gateway')->get($key); if (empty($addresses_list)) { return; } // 循环遍历,查找未连接的gateway ip 端口 foreach ($addresses_list as $addr) { if (!isset($this->gatewayConnections[$addr])) { // 执行连接 $conn = @stream_socket_client("tcp://{$addr}", $errno, $errstr, 1); if (!$conn) { if (!isset($this->badGatewayAddress[$addr])) { $this->badGatewayAddress[$addr] = 0; } // 删除连不上的端口 if ($this->badGatewayAddress[$addr]++ > self::MAX_RETRY_COUNT) { \Man\Core\Lib\Mutex::get(); $addresses_list = Store::instance('gateway')->get($key); unset($addresses_list[$addr]); Store::instance('gateway')->set($key, $addresses_list); $this->notice("tcp://{$addr} " . $errstr . " del {$addr} from store", false); \Man\Core\Lib\Mutex::release(); } continue; } unset($this->badGatewayAddress[$addr]); $this->gatewayConnections[$addr] = $conn; stream_set_blocking($this->gatewayConnections[$addr], 0); // 初始化一些值 $fd = (int) $this->gatewayConnections[$addr]; $this->connections[$fd] = $this->gatewayConnections[$addr]; $this->recvBuffers[$fd] = array('buf' => '', 'remain_len' => $this->prereadLength); // 添加数据可读事件 $this->event->add($this->connections[$fd], \Man\Core\Events\BaseEvent::EV_READ, array($this, 'dealInputBase'), $fd); } } }
/** * 删除全局的通信地址 * @param string $address */ protected function unregisterAddress($address) { // 这里使用了信号量只能实现单机互斥,分布式互斥需要借助于memcache incr 或者其他分布式存储 \Man\Core\Lib\Mutex::get(); $key = 'GLOBAL_GATEWAY_ADDRESS'; $addresses_list = Store::instance('gateway')->get($key); if (empty($addresses_list)) { $addresses_list = array(); } unset($addresses_list[$address]); Store::instance('gateway')->set($key, $addresses_list); \Man\Core\Lib\Mutex::release(); }
/** * 删除全局的通信地址 * @param string $address */ protected function unregisterAddress($address) { // 统计打点 StatisticClient::tick(__CLASS__, 'unregisterAddress'); // 这里使用了信号量只能实现单机互斥,分布式互斥需要借助于memcached incr cas或者其他分布式存储 \Man\Core\Lib\Mutex::get(); // key $key = 'GLOBAL_GATEWAY_ADDRESS'; // 获取存储实例 try { $store = Store::instance('gateway'); } catch (\Exception $msg) { StatisticClient::report(__CLASS__, 'unregisterAddress', 0, 108, $msg); \Man\Core\Lib\Mutex::release(); return false; } // 获取数据 $addresses_list = $store->get($key); if (empty($addresses_list)) { $addresses_list = array(); } // 去掉要删除的数据 unset($addresses_list[$address]); // 保存数据 if (!$store->set($key, $addresses_list)) { \Man\Core\Lib\Mutex::release(); $msg = "删除gateway通信地址出错"; if (get_class($store) == 'Memcached') { $msg .= " 原因:" . $store->getResultMessage(); } $this->notice($msg); StatisticClient::report(__CLASS__, 'unregisterAddress', 0, 108, new \Exception($msg)); return; } // 存储成功 \Man\Core\Lib\Mutex::release(); StatisticClient::report(__CLASS__, 'unregisterAddress', 1, 0, ''); }
/** * 存储全局的通信地址 * @param string $address * @todo 用锁机制等保证数据完整性 */ protected function registerAddress($address) { \Man\Core\Lib\Mutex::get(); $key = 'GLOBAL_GATEWAY_ADDRESS'; $addresses_list = Store::get($key); if (empty($addresses_list)) { $addresses_list = array(); } $addresses_list[$address] = $address; Store::set($key, $addresses_list); \Man\Core\Lib\Mutex::release(); }