From 588aea5c8e33d020339b9ab524d96e892e8eafd4 Mon Sep 17 00:00:00 2001 From: Daniil Gentili Date: Sun, 1 Apr 2018 19:23:20 +0200 Subject: [PATCH] Stability fixes --- src/danog/MadelineProto/Connection.php | 10 +++-- src/danog/MadelineProto/DataCenter.php | 4 +- .../MTProtoTools/CallHandler.php | 6 ++- .../MTProtoTools/UpdateHandler.php | 44 +++++++++++-------- 4 files changed, 39 insertions(+), 25 deletions(-) diff --git a/src/danog/MadelineProto/Connection.php b/src/danog/MadelineProto/Connection.php index 5b90ae78..1e404411 100644 --- a/src/danog/MadelineProto/Connection.php +++ b/src/danog/MadelineProto/Connection.php @@ -264,10 +264,11 @@ class Connection case 'obfuscated2': $packet = ''; while (strlen($packet) < $length) { - $packet .= $this->sock->read($length - strlen($packet)); - if ($packet === false || strlen($packet) === 0) { + $piece = $this->sock->read($length - strlen($packet)); + if ($piece === false || strlen($piece) === 0) { throw new \danog\MadelineProto\NothingInTheSocketException(\danog\MadelineProto\Lang::$current_lang['nothing_in_socket']); } + $packet .= $piece; } return @$this->obfuscated['decryption']->encrypt($packet); @@ -278,10 +279,11 @@ class Connection case 'https': $packet = ''; while (strlen($packet) < $length) { - $packet .= $this->sock->read($length - strlen($packet)); - if ($packet === false || strlen($packet) === 0) { + $piece = $this->sock->read($length - strlen($packet)); + if ($piece === false || strlen($piece) === 0) { throw new \danog\MadelineProto\NothingInTheSocketException(\danog\MadelineProto\Lang::$current_lang['nothing_in_socket']); } + $packet .= $piece; } return $packet; diff --git a/src/danog/MadelineProto/DataCenter.php b/src/danog/MadelineProto/DataCenter.php index c9e79165..5d2cc163 100644 --- a/src/danog/MadelineProto/DataCenter.php +++ b/src/danog/MadelineProto/DataCenter.php @@ -145,7 +145,7 @@ class DataCenter return $all ? array_keys((array) $this->dclist[$test][$ipv6]) : array_keys((array) $this->sockets); } - public function select() + public function select($poll = false) { $read = []; $write = []; @@ -153,7 +153,7 @@ class DataCenter foreach ($this->sockets as $dc_id => $socket) { $read[$dc_id] = $socket->getSocket(); } - \Socket::select($read, $write, $except, $this->settings['all']['timeout']); + \Socket::select($read, $write, $except, $poll ? 0 : $this->settings['all']['timeout']); return array_keys($read); } diff --git a/src/danog/MadelineProto/MTProtoTools/CallHandler.php b/src/danog/MadelineProto/MTProtoTools/CallHandler.php index 551c9428..993acd0b 100644 --- a/src/danog/MadelineProto/MTProtoTools/CallHandler.php +++ b/src/danog/MadelineProto/MTProtoTools/CallHandler.php @@ -143,7 +143,11 @@ trait CallHandler $server_answer = null; $update_count = 0; $only_updates = false; - while ($server_answer === null && $res_count++ < $this->settings['max_tries']['response'] + 1) { + $response_tries = $this->settings['max_tries']['response'] + 1; + if ($last_recv) { + $response_tries += (int) floor((time() - $last_recv)/10); + } + while ($server_answer === null && $res_count++ < $response_tries) { // Loop until we get a response, loop for a max of $this->settings['max_tries']['response'] times try { \danog\MadelineProto\Logger::log('Getting response (try number '.$res_count.' for '.$method.')...', \danog\MadelineProto\Logger::ULTRA_VERBOSE); diff --git a/src/danog/MadelineProto/MTProtoTools/UpdateHandler.php b/src/danog/MadelineProto/MTProtoTools/UpdateHandler.php index 683975a2..8e492d75 100644 --- a/src/danog/MadelineProto/MTProtoTools/UpdateHandler.php +++ b/src/danog/MadelineProto/MTProtoTools/UpdateHandler.php @@ -61,31 +61,39 @@ trait UpdateHandler $time = microtime(true); try { - if (!$this->is_http($this->datacenter->curdc) || $this->altervista) { + if (!$this->is_http($this->datacenter->curdc) && !$this->altervista) { try { $waiting = $this->datacenter->select(); - $dc = count($waiting) ? $waiting[0] : $this->datacenter->curdc; - $last_recv = $this->datacenter->sockets[$dc]->last_recv; if (count($waiting)) { - if (($error = $this->recv_message($dc)) !== true) { - if ($error === -404) { - if ($this->datacenter->sockets[$dc]->temp_auth_key !== null) { - \danog\MadelineProto\Logger::log('WARNING: Resetting auth key...', \danog\MadelineProto\Logger::WARNING); - $this->datacenter->sockets[$dc]->temp_auth_key = null; - $this->init_authorization(); + $tries = 10; + while (count($waiting) && $tries--) { + $dc = $waiting[0]; + if (($error = $this->recv_message($dc)) !== true) { + if ($error === -404) { + if ($this->datacenter->sockets[$dc]->temp_auth_key !== null) { + \danog\MadelineProto\Logger::log('WARNING: Resetting auth key...', \danog\MadelineProto\Logger::WARNING); + $this->datacenter->sockets[$dc]->temp_auth_key = null; + $this->init_authorization(); - throw new \danog\MadelineProto\Exception('I had to recreate the temporary authorization key'); + throw new \danog\MadelineProto\Exception('I had to recreate the temporary authorization key'); + } } - } - throw new \danog\MadelineProto\RPCErrorException($error, $error); + throw new \danog\MadelineProto\RPCErrorException($error, $error); + } + $only_updates = $this->handle_messages($dc); + $waiting = $this->datacenter->select(true); } - $only_updates = $this->handle_messages($dc); + } else { + $this->get_updates_difference(); } } catch (\danog\MadelineProto\NothingInTheSocketException $e) { + $this->get_updates_difference(); } + } else { + $this->get_updates_difference(); } - if ($this->is_http($dc) || $this->altervista && time() - $this->last_getdifference > $this->settings['updates']['getdifference_interval']) { + if (time() - $this->last_getdifference > $this->settings['updates']['getdifference_interval']) { $this->get_updates_difference(); } } catch (\danog\MadelineProto\RPCErrorException $e) { @@ -294,7 +302,7 @@ trait UpdateHandler \danog\MadelineProto\Logger::log('Fetching normal difference...', \danog\MadelineProto\Logger::ULTRA_VERBOSE); while (!isset($difference)) { try { - $difference = $this->method_call('updates.getDifference', ['pts' => $this->load_update_state()['pts'], 'date' => $this->load_update_state()['date'], 'qts' => $this->load_update_state()['qts']], ['datacenter' => $this->datacenter->curdc]); + $difference = $this->method_call('updates.getDifference', ['pts' => $this->load_update_state()['pts'], 'date' => $this->load_update_state()['date'], 'qts' => $this->load_update_state()['qts']], ['datacenter' => $this->settings['connection_settings']['default_dc']]); } catch (\danog\MadelineProto\PTSException $e) { $this->updates_state['sync_loading'] = false; $this->got_state = false; @@ -348,8 +356,8 @@ trait UpdateHandler $this->updates_state['sync_loading'] = true; try { - $data = $this->method_call('updates.getState', [], ['datacenter' => $this->datacenter->curdc]); - $this->get_cdn_config($this->datacenter->curdc); + $data = $this->method_call('updates.getState', [], ['datacenter' => $this->settings['connection_settings']['default_dc']]); + $this->get_cdn_config( $this->settings['connection_settings']['default_dc']); } finally { $this->updates_state['sync_loading'] = $last; } @@ -565,7 +573,7 @@ trait UpdateHandler return false; } \danog\MadelineProto\Logger::log('Applying qts: '.$update['qts'].' over current qts '.$cur_state['qts'].', chat id: '.$update['message']['chat_id'], \danog\MadelineProto\Logger::VERBOSE); - $this->method_call('messages.receivedQueue', ['max_qts' => $cur_state['qts'] = $update['qts']], ['datacenter' => $this->datacenter->curdc]); + $this->method_call('messages.receivedQueue', ['max_qts' => $cur_state['qts'] = $update['qts']], ['datacenter' => $this->settings['connection_settings']['default_dc']]); $this->handle_encrypted_update($update); return;