Fixed response handling

This commit is contained in:
Daniil Gentili 2016-11-29 23:02:17 +00:00
parent 0cc2ea1cef
commit 0c578f25c9
3 changed files with 41 additions and 32 deletions

View File

@ -17,26 +17,6 @@ namespace danog\MadelineProto\MTProtoTools;
*/
class CallHandler extends AuthKeyHandler
{
public function wait_for_response()
{
foreach ($this->datacenter->new_outgoing as $key => $current) {
$response = null;
$count = 0;
while ($response == null && $count++ < $this->settings['max_tries']['response']) {
\danog\MadelineProto\Logger::log('Getting response (try number '.$count.' for '.$current['method'].')...');
$this->recv_message();
$this->handle_messages($current);
if (isset($this->datacenter->incoming_messages[$this->datacenter->outgoing_messages[$current['msg_id']]['response']]['content'])) {
$response = $this->datacenter->incoming_messages[$this->datacenter->outgoing_messages[$current['msg_id']]['response']]['content'];
}
}
if ($response === null) {
\danog\MadelineProto\Logger::log('Could not get response for '.$current['method'].'!');
} else {
unset($this->datacenter->new_outgoing[$key]);
}
}
}
public function method_call($method, $args = [], $message_id = null)
{
@ -50,11 +30,17 @@ class CallHandler extends AuthKeyHandler
$int_message_id = $this->send_message($this->tl->serialize_method($method, $args), $this->tl->content_related($method), $message_id);
$this->datacenter->outgoing_messages[$int_message_id]['content'] = ['method' => $method, 'args' => $args];
$this->datacenter->new_outgoing[$int_message_id] = ['msg_id' => $int_message_id, 'method' => $method, 'type' => $this->tl->methods->find_by_method($method)['type']];
$this->wait_for_response();
if (!isset($this->datacenter->incoming_messages[$this->datacenter->outgoing_messages[$int_message_id]['response']]['content'])) {
throw new \danog\MadelineProto\Exception("Response isn't yet present!");
$res_count = 0;
$server_answer = null;
while ($server_answer === null && $res_count++ < $this->settings['max_tries']['response']) {
\danog\MadelineProto\Logger::log('Getting response (try number '.$res_count.' for '.$method.')...');
$this->recv_message();
$this->handle_messages();
if (!isset($this->datacenter->incoming_messages[$this->datacenter->outgoing_messages[$int_message_id]['response']]['content'])) {
continue;
}
$server_answer = $this->datacenter->incoming_messages[$this->datacenter->outgoing_messages[$int_message_id]['response']]['content'];
}
$server_answer = $this->datacenter->incoming_messages[$this->datacenter->outgoing_messages[$int_message_id]['response']]['content'];
if ($server_answer == null) {
throw new \danog\MadelineProto\Exception("Couldn't get response");
}

View File

@ -17,7 +17,7 @@ namespace danog\MadelineProto\MTProtoTools;
*/
class ResponseHandler extends MsgIdHandler
{
public function handle_messages($expecting)
public function handle_messages()
{
foreach ($this->datacenter->new_incoming as $current_msg_id) {
$response = $this->datacenter->incoming_messages[$current_msg_id]['content'];
@ -37,6 +37,7 @@ class ResponseHandler extends MsgIdHandler
$this->ack_outgoing_message_id($response['req_msg_id']); // Acknowledge that the server received my request
$this->datacenter->outgoing_messages[$response['req_msg_id']]['response'] = $current_msg_id;
unset($this->datacenter->new_incoming[$current_msg_id]);
unset($this->datacenter->new_outgoing[$response['req_msg_id']]);
break;
case 'bad_server_salt':
@ -44,6 +45,7 @@ class ResponseHandler extends MsgIdHandler
$this->ack_outgoing_message_id($response['bad_msg_id']); // Acknowledge that the server received my request
$this->datacenter->outgoing_messages[$response['bad_msg_id']]['response'] = $current_msg_id;
unset($this->datacenter->new_incoming[$current_msg_id]);
unset($this->datacenter->new_outgoing[$response['bad_msg_id']]);
break;
case 'pong':
@ -53,6 +55,7 @@ class ResponseHandler extends MsgIdHandler
$omessage['response'] = $response['msg_id'];
$this->datacenter->incoming_messages[$response['msg_id']]['content'] = $response;
unset($this->datacenter->new_incoming[$current_msg_id]);
unset($this->datacenter->new_outgoing[$msg_id]);
}
}
break;
@ -72,7 +75,7 @@ class ResponseHandler extends MsgIdHandler
$this->datacenter->incoming_messages[$message['msg_id']] = ['seq_no' => $message['seqno'], 'content' => $message['body']];
$this->datacenter->new_incoming[$message['msg_id']] = $message['msg_id'];
$this->handle_messages($expecting);
$this->handle_messages();
}
break;
case 'msg_copy':
@ -84,7 +87,7 @@ class ResponseHandler extends MsgIdHandler
$this->datacenter->incoming_messages[$message['orig_message']['msg_id']] = ['content' => $response['orig_message']];
$this->datacenter->new_incoming[$message['orig_message']['msg_id']] = $message['orig_message']['msg_id'];
$this->handle_messages($expecting);
$this->handle_messages();
}
unset($this->datacenter->new_incoming[$current_msg_id]);
break;
@ -98,12 +101,15 @@ class ResponseHandler extends MsgIdHandler
$this->ack_outgoing_message_id($response['req_msg_id']); // Acknowledge that the server received the original query (the same one, the response to which we wish to forget)
default:
$this->ack_incoming_message_id($current_msg_id); // Acknowledge that I received the server's response
if ($this->tl->constructors->find_by_predicate($this->datacenter->response['_'])['type'] == $expecting['type']) {
$this->datacenter->outgoing_messages[$expecting['msg_id']]['response'] = $response;
unset($this->datacenter->new_incoming[$current_msg_id]);
} else {
throw new \danog\MadelineProto\ResponseException('Dunno how to handle '.PHP_EOL.var_export($response, true));
foreach ($this->datacenter->new_outgoing as $expecting) {
if ($this->tl->constructors->find_by_predicate($response['_'])['type'] == $expecting['type']) {
$this->datacenter->outgoing_messages[$expecting['msg_id']]['response'] = $current_msg_id;
unset($this->datacenter->new_outgoing[$expecting['msg_id']]);
unset($this->datacenter->new_incoming[$current_msg_id]);
return;
}
}
throw new \danog\MadelineProto\ResponseException('Dunno how to handle '.PHP_EOL.var_export($response, true));
break;
}
}

View File

@ -0,0 +1,17 @@
<?php
/*
Copyright 2016 Daniil Gentili
(https://daniil.it)
This file is part of MadelineProto.
MadelineProto is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
MadelineProto is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Affero General Public License for more details.
You should have received a copy of the GNU General Public License along with MadelineProto.
If not, see <http://www.gnu.org/licenses/>.
*/
namespace danog\MadelineProto;
class ResponseException extends \Exception
{
}