Implement select in DataCenter class, continue writing VoIP implementatino

This commit is contained in:
Daniil Gentili 2018-03-29 13:25:15 +02:00
parent 2c83a555fc
commit cf974a2d0a
9 changed files with 104 additions and 16 deletions

View File

@ -77,11 +77,6 @@ Works exactly like the [socket_accept](http://php.net/manual/en/function.socket-
`public function select(array &$read, array &$write, array &$except, int $tv_sec, int $tv_usec = 0);`
Works exactly like the [socket_select](http://php.net/manual/en/function.socket-select.php) function.
`public function read(int $length, [ int $flags = 0 ]);` `public function read(int $length, [ int $flags = 0 ]);`
@ -91,7 +86,7 @@ Works exactly like the [socket_read](http://php.net/manual/en/function.socket-re
`public function write(string $buffer, [ int $length ]);` `public function write(string $buffer, [ int $length ]);`
Works exactly like the [socket_read](http://php.net/manual/en/function.socket-write.php) function. Works exactly like the [socket_write](http://php.net/manual/en/function.socket-write.php) function.
@ -120,4 +115,8 @@ Works like [socket_getsockname](http://php.net/manual/en/function.socket-getsock
Can return additional HTTP headers to use when the HTTP protocol is being used. Can return additional HTTP headers to use when the HTTP protocol is being used.
<form action="https://docs.madelineproto.xyz/docs/LUA.html"><input type="submit" value="Previous section" /></form><form action="https://docs.madelineproto.xyz/docs/CONTRIB.html"><input type="submit" value="Next section" /></form> `public function getResource();`
Returns the resource used for socket communication: should call `$socket->getResource()`.
<form action="https://docs.madelineproto.xyz/docs/LUA.html"><input type="submit" value="Previous section" /></form><form action="https://docs.madelineproto.xyz/docs/CONTRIB.html"><input type="submit" value="Next section" /></form>

View File

@ -192,4 +192,8 @@ class CustomHTTPProxy implements \danog\MadelineProto\Proxy
{ {
$this->options = $extra; $this->options = $extra;
} }
public function getResource()
{
return $this->sock->getResource();
}
} }

View File

@ -185,4 +185,8 @@ class HttpProxy implements \danog\MadelineProto\Proxy
public function getProxyHeaders() public function getProxyHeaders()
{ {
} }
public function getResource()
{
return $this->sock->getResource();
}
} }

View File

@ -81,9 +81,31 @@ If not, see <http://www.gnu.org/licenses/>.
return true; return true;
} }
public function select(array &$read, array &$write, array &$except, int $tv_sec, int $tv_usec = 0) public static function select(array &$read, array &$write, array &$except, int $tv_sec, int $tv_usec = 0)
{ {
return stream_select($read, $write, $except, $tv_sec, $tv_usec); $actual_read = [];
foreach ($read as $key => $resource) {
$actual_read[$key] = $resource->getResource();
}
$actual_write = [];
foreach ($write as $key => $resource) {
$actual_write[$key] = $resource->getResource();
}
$actual_except = [];
foreach ($except as $key => $resource) {
$actual_except[$key] = $resource->getResource();
}
$res = stream_select($actual_read, $actual_write, $actual_except, $tv_sec, $tv_usec);
foreach ($read as $key => $resource) {
if (!isset($actual_read[$key])) unset($read[$key]);
}
foreach ($write as $key => $resource) {
if (!isset($actual_write[$key])) unset($write[$key]);
}
foreach ($except as $key => $resource) {
if (!isset($actual_except[$key])) unset($except[$key]);
}
return $res;
} }
public function read(int $length, int $flags = 0) public function read(int $length, int $flags = 0)
@ -125,6 +147,10 @@ If not, see <http://www.gnu.org/licenses/>.
{ {
return ''; return '';
} }
public function getResource()
{
return $this->sock;
}
} }
if (!extension_loaded('pthreads')) { if (!extension_loaded('pthreads')) {
@ -191,11 +217,34 @@ if (!extension_loaded('pthreads')) {
return socket_connect($this->sock, $address, $port); return socket_connect($this->sock, $address, $port);
} }
public function select(array &$read, array &$write, array &$except, int $tv_sec, int $tv_usec = 0) public static function select(array &$read, array &$write, array &$except, int $tv_sec, int $tv_usec = 0)
{ {
return socket_select($read, $write, $except, $tv_sec, $tv_usec); $actual_read = [];
foreach ($read as $key => $resource) {
$actual_read[$key] = $resource->getResource();
}
$actual_write = [];
foreach ($write as $key => $resource) {
$actual_write[$key] = $resource->getResource();
}
$actual_except = [];
foreach ($except as $key => $resource) {
$actual_except[$key] = $resource->getResource();
}
$res = socket_select($actual_read, $actual_write, $actual_except, $tv_sec, $tv_usec);
foreach ($read as $key => $resource) {
if (!isset($actual_read[$key])) unset($read[$key]);
}
foreach ($write as $key => $resource) {
if (!isset($actual_write[$key])) unset($write[$key]);
}
foreach ($except as $key => $resource) {
if (!isset($actual_except[$key])) unset($except[$key]);
}
return $res;
} }
public function read(int $length, int $flags = 0) public function read(int $length, int $flags = 0)
{ {
return socket_read($this->sock, $length, $flags); return socket_read($this->sock, $length, $flags);
@ -239,6 +288,10 @@ if (!extension_loaded('pthreads')) {
{ {
return ''; return '';
} }
public function getResource()
{
return $this->sock;
}
} }
class Socket extends SocketBase class Socket extends SocketBase
{ {

View File

@ -20,6 +20,12 @@ class Connection
{ {
use \danog\Serializable; use \danog\Serializable;
use \danog\MadelineProto\Tools; use \danog\MadelineProto\Tools;
const API_ENDPOINT = 0;
const VOIP_UDP_REFLECTOR_ENDPOINT = 1;
const VOIP_TCP_REFLECTOR_ENDPOINT = 2;
const VOIP_UDP_P2P_ENDPOINT = 3;
const VOIP_UDP_LAN_ENDPOINT = 4;
public $sock = null; public $sock = null;
public $protocol = null; public $protocol = null;
public $ip = null; public $ip = null;
@ -27,6 +33,8 @@ class Connection
public $timeout = null; public $timeout = null;
public $parsed = []; public $parsed = [];
public $time_delta = 0; public $time_delta = 0;
public $type = 0;
public $peer_tag;
public $temp_auth_key; public $temp_auth_key;
public $auth_key; public $auth_key;
public $session_id; public $session_id;
@ -208,7 +216,7 @@ class Connection
public function __sleep() public function __sleep()
{ {
return ['proxy', 'extra', 'protocol', 'ip', 'port', 'timeout', 'parsed', 'time_delta', 'temp_auth_key', 'auth_key', 'session_id', 'session_out_seq_no', 'session_in_seq_no', 'ipv6', 'incoming_messages', 'outgoing_messages', 'new_incoming', 'new_outgoing', 'max_incoming_id', 'max_outgoing_id', 'obfuscated', 'authorized', 'object_queue', 'ack_queue']; return ['proxy', 'extra', 'protocol', 'ip', 'port', 'timeout', 'parsed', 'time_delta', 'peer_tag', 'temp_auth_key', 'auth_key', 'session_id', 'session_out_seq_no', 'session_in_seq_no', 'ipv6', 'incoming_messages', 'outgoing_messages', 'new_incoming', 'new_outgoing', 'max_incoming_id', 'max_outgoing_id', 'obfuscated', 'authorized', 'object_queue', 'ack_queue'];
} }
public function __wakeup() public function __wakeup()
@ -405,4 +413,8 @@ class Connection
return ['protocol' => $protocol, 'code' => $code, 'description' => $description, 'body' => $read, 'headers' => $headers]; return ['protocol' => $protocol, 'code' => $code, 'description' => $description, 'body' => $read, 'headers' => $headers];
} }
public function getSocket()
{
return $this->sock;
}
} }

View File

@ -144,4 +144,15 @@ class DataCenter
return $all ? array_keys((array) $this->dclist[$test][$ipv6]) : array_keys((array) $this->sockets); return $all ? array_keys((array) $this->dclist[$test][$ipv6]) : array_keys((array) $this->sockets);
} }
public function select()
{
$read = [];
$write = [];
$except = [];
foreach ($this->sockets as $dc_id => $socket) {
$read [$dc_id] = $socket->getSocket();
}
\Socket::select($read, $write, $except, 0);
return array_keys($read);
}
} }

View File

@ -31,8 +31,6 @@ interface Proxy
public function connect($address, $port = 0); public function connect($address, $port = 0);
public function select(array &$read, array &$write, array &$except, $tv_sec, $tv_usec = 0);
public function read($length, $flags = 0); public function read($length, $flags = 0);
public function write($buffer, $length = -1); public function write($buffer, $length = -1);
@ -48,4 +46,6 @@ interface Proxy
public function getProxyHeaders(); public function getProxyHeaders();
public function setExtra(array $extra = []); public function setExtra(array $extra = []);
public function getResource();
} }

View File

@ -226,6 +226,11 @@ if (!extension_loaded('php-libtgvoip') && false) {
private function init_all() private function init_all()
{ {
foreach ($this->datacenter->sockets as $dc_id => $socket) {
if ($socket->auth_key === NULL) {
$socket->auth_key = ['id' => $this->configuration['auth_key_id'], 'auth_key' => $this->configuration['auth_key']];
}
}
} }
public function getCallState() public function getCallState()

View File

@ -130,7 +130,7 @@ trait AuthKeyHandler
$this->calls[$params['id']]->setVisualization($visualization); $this->calls[$params['id']]->setVisualization($visualization);
$this->calls[$params['id']]->configuration['shared_config'] = array_merge($this->method_call('phone.getCallConfig', [], ['datacenter' => $this->datacenter->curdc]), $this->calls[$params['id']]->configuration['shared_config']); $this->calls[$params['id']]->configuration['shared_config'] = array_merge($this->method_call('phone.getCallConfig', [], ['datacenter' => $this->datacenter->curdc]), $this->calls[$params['id']]->configuration['shared_config']);
$this->calls[$params['id']]->configuration['endpoints'] = array_merge([$res['connection']], $res['alternative_connections'], $this->calls[$params['id']]->configuration['endpoints']); $this->calls[$params['id']]->configuration['endpoints'] = array_merge([$res['connection']], $res['alternative_connections'], $this->calls[$params['id']]->configuration['endpoints']);
$this->calls[$params['id']]->configuration = array_merge(['recv_timeout' => $this->config['call_receive_timeout_ms'] / 1000, 'init_timeout' => $this->config['call_connect_timeout_ms'] / 1000, 'data_saving' => \danog\MadelineProto\VoIP::DATA_SAVING_NEVER, 'enable_NS' => true, 'enable_AEC' => true, 'enable_AGC' => true, 'auth_key' => $key, 'network_type' => \danog\MadelineProto\VoIP::NET_TYPE_ETHERNET], $this->calls[$params['id']]->configuration); $this->calls[$params['id']]->configuration = array_merge(['recv_timeout' => $this->config['call_receive_timeout_ms'] / 1000, 'init_timeout' => $this->config['call_connect_timeout_ms'] / 1000, 'data_saving' => \danog\MadelineProto\VoIP::DATA_SAVING_NEVER, 'enable_NS' => true, 'enable_AEC' => true, 'enable_AGC' => true, 'auth_key' => $key, 'auth_key_id' => substr(sha1($key, true), -8), 'call_id' => substr(hash('sha256', $key, true), -16), 'network_type' => \danog\MadelineProto\VoIP::NET_TYPE_ETHERNET], $this->calls[$params['id']]->configuration);
$this->calls[$params['id']]->parseConfig(); $this->calls[$params['id']]->parseConfig();
$res = $this->calls[$params['id']]->startTheMagic(); $res = $this->calls[$params['id']]->startTheMagic();
$this->handle_pending_updates(); $this->handle_pending_updates();
@ -173,7 +173,7 @@ trait AuthKeyHandler
$this->calls[$params['id']]->setVisualization($visualization); $this->calls[$params['id']]->setVisualization($visualization);
$this->calls[$params['id']]->configuration['shared_config'] = array_merge($this->method_call('phone.getCallConfig', [], ['datacenter' => $this->datacenter->curdc]), $this->calls[$params['id']]->configuration['shared_config']); $this->calls[$params['id']]->configuration['shared_config'] = array_merge($this->method_call('phone.getCallConfig', [], ['datacenter' => $this->datacenter->curdc]), $this->calls[$params['id']]->configuration['shared_config']);
$this->calls[$params['id']]->configuration['endpoints'] = array_merge([$params['connection']], $params['alternative_connections'], $this->calls[$params['id']]->configuration['endpoints']); $this->calls[$params['id']]->configuration['endpoints'] = array_merge([$params['connection']], $params['alternative_connections'], $this->calls[$params['id']]->configuration['endpoints']);
$this->calls[$params['id']]->configuration = array_merge(['recv_timeout' => $this->config['call_receive_timeout_ms'] / 1000, 'init_timeout' => $this->config['call_connect_timeout_ms'] / 1000, 'data_saving' => \danog\MadelineProto\VoIP::DATA_SAVING_NEVER, 'enable_NS' => true, 'enable_AEC' => true, 'enable_AGC' => true, 'auth_key' => $key, 'network_type' => \danog\MadelineProto\VoIP::NET_TYPE_ETHERNET], $this->calls[$params['id']]->configuration); $this->calls[$params['id']]->configuration = array_merge(['recv_timeout' => $this->config['call_receive_timeout_ms'] / 1000, 'init_timeout' => $this->config['call_connect_timeout_ms'] / 1000, 'data_saving' => \danog\MadelineProto\VoIP::DATA_SAVING_NEVER, 'enable_NS' => true, 'enable_AEC' => true, 'enable_AGC' => true, 'auth_key' => $key, 'auth_key_id' => substr(sha1($key, true), -8), 'call_id' => substr(hash('sha256', $key, true), -16), 'network_type' => \danog\MadelineProto\VoIP::NET_TYPE_ETHERNET], $this->calls[$params['id']]->configuration);
$this->calls[$params['id']]->parseConfig(); $this->calls[$params['id']]->parseConfig();
return $this->calls[$params['id']]->startTheMagic(); return $this->calls[$params['id']]->startTheMagic();