2019-08-31 22:43:58 +02:00
< ? php
2020-01-31 19:29:43 +01:00
2019-08-31 22:43:58 +02:00
/**
* Connection module handling all connections to a datacenter .
*
* 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 />.
*
* @ author Daniil Gentili < daniil @ daniil . it >
2020-02-17 14:13:46 +01:00
* @ copyright 2016 - 2020 Daniil Gentili < daniil @ daniil . it >
2019-08-31 22:43:58 +02:00
* @ license https :// opensource . org / licenses / AGPL - 3.0 AGPLv3
*
2019-10-31 15:07:35 +01:00
* @ link https :// docs . madelineproto . xyz MadelineProto documentation
2019-08-31 22:43:58 +02:00
*/
namespace danog\MadelineProto ;
2019-12-29 14:04:02 +01:00
use Amp\Deferred ;
use Amp\Promise ;
use Amp\Success ;
2020-07-28 20:39:32 +02:00
use danog\MadelineProto\Loop\Generic\PeriodicLoopInternal ;
2019-09-02 15:30:29 +02:00
use danog\MadelineProto\MTProto\AuthKey ;
use danog\MadelineProto\MTProto\PermAuthKey ;
use danog\MadelineProto\MTProto\TempAuthKey ;
2020-09-22 11:48:12 +02:00
use danog\MadelineProto\Settings\Connection as ConnectionSettings ;
2019-08-31 22:43:58 +02:00
use danog\MadelineProto\Stream\ConnectionContext ;
2019-09-02 14:37:30 +02:00
use danog\MadelineProto\Stream\MTProtoTransport\HttpsStream ;
use danog\MadelineProto\Stream\MTProtoTransport\HttpStream ;
2019-09-17 21:35:53 +02:00
use danog\MadelineProto\Stream\Transport\WssStream ;
2019-09-01 14:07:04 +02:00
use JsonSerializable ;
2019-08-31 22:43:58 +02:00
2020-10-01 20:48:22 +02:00
/**
* Datacenter connection
*/
2019-09-01 14:07:04 +02:00
class DataCenterConnection implements JsonSerializable
2019-08-31 22:43:58 +02:00
{
2019-09-02 16:54:36 +02:00
const READ_WEIGHT = 1 ;
const READ_WEIGHT_MEDIA = 5 ;
const WRITE_WEIGHT = 10 ;
2019-12-29 14:04:02 +01:00
/**
* Promise for connection .
*
* @ var Promise
*/
private $connectionsPromise ;
/**
* Deferred for connection .
*
* @ var Deferred
*/
private $connectionsDeferred ;
2019-08-31 22:43:58 +02:00
/**
* Temporary auth key .
*
2019-09-01 23:39:29 +02:00
* @ var TempAuthKey | null
2019-08-31 22:43:58 +02:00
*/
private $tempAuthKey ;
/**
* Permanent auth key .
*
2019-09-01 23:39:29 +02:00
* @ var PermAuthKey | null
2019-08-31 22:43:58 +02:00
*/
2019-09-02 16:54:36 +02:00
private $permAuthKey ;
2019-08-31 22:43:58 +02:00
/**
2019-09-01 01:52:28 +02:00
* Connections open to a certain DC .
2019-08-31 22:43:58 +02:00
*
2020-10-01 20:48:22 +02:00
* @ var array < int , Connection >
2019-08-31 22:43:58 +02:00
*/
private $connections = [];
2019-09-01 01:52:28 +02:00
/**
2019-09-01 14:07:04 +02:00
* Connection weights .
2019-09-01 01:52:28 +02:00
*
2020-10-01 20:48:22 +02:00
* @ var array < int , int >
2019-09-01 01:52:28 +02:00
*/
private $availableConnections = [];
2019-08-31 22:43:58 +02:00
/**
2019-09-01 01:52:28 +02:00
* Main API instance .
2019-08-31 22:43:58 +02:00
*
* @ var \danog\MadelineProto\MTProto
*/
private $API ;
/**
2019-09-01 01:52:28 +02:00
* Connection context .
2019-08-31 22:43:58 +02:00
*
* @ var ConnectionContext
*/
private $ctx ;
/**
2019-09-01 01:52:28 +02:00
* DC ID .
2019-08-31 22:43:58 +02:00
*
* @ var string
*/
private $datacenter ;
2019-09-01 01:52:28 +02:00
/**
2019-09-01 23:39:29 +02:00
* Linked DC ID .
2019-09-01 01:52:28 +02:00
*
2019-09-01 23:39:29 +02:00
* @ var string
2019-09-01 01:52:28 +02:00
*/
2019-09-01 23:39:29 +02:00
private $linked ;
2019-09-01 01:52:28 +02:00
/**
2019-09-01 14:07:04 +02:00
* Loop to keep weights at sane value .
2019-09-01 01:52:28 +02:00
*/
2020-07-28 20:39:32 +02:00
private ? PeriodicLoopInternal $robinLoop = null ;
2019-09-02 14:37:30 +02:00
/**
* Decrement roundrobin weight by this value if busy reading .
*
* @ var integer
*/
private $decRead = 1 ;
/**
* Decrement roundrobin weight by this value if busy writing .
*
* @ var integer
*/
private $decWrite = 10 ;
2019-09-04 17:48:07 +02:00
/**
2019-09-12 18:56:26 +02:00
* Backed up messages .
2019-09-04 17:48:07 +02:00
*
* @ var array
*/
private $backup = [];
2019-09-17 21:35:53 +02:00
/**
* Whether this socket has to be reconnected .
*
* @ var boolean
*/
private $needsReconnect = false ;
/**
* Indicate if this socket needs to be reconnected .
*
* @ param boolean $needsReconnect Whether the socket has to be reconnected
*
* @ return void
*/
public function needReconnect ( bool $needsReconnect )
{
$this -> needsReconnect = $needsReconnect ;
}
/**
* Whether this sockets needs to be reconnected .
*
* @ return boolean
*/
public function shouldReconnect () : bool
{
return $this -> needsReconnect ;
}
2019-08-31 22:43:58 +02:00
/**
* Get auth key .
*
* @ param boolean $temp Whether to fetch the temporary auth key
*
2019-09-01 14:07:04 +02:00
* @ return AuthKey
2019-08-31 22:43:58 +02:00
*/
2019-09-01 14:07:04 +02:00
public function getAuthKey ( bool $temp = true ) : AuthKey
2019-08-31 22:43:58 +02:00
{
2019-09-02 16:54:36 +02:00
return $this -> { $temp ? 'tempAuthKey' : 'permAuthKey' };
2019-08-31 22:43:58 +02:00
}
/**
* Check if auth key is present .
*
2019-09-01 23:39:29 +02:00
* @ param boolean | null $temp Whether to fetch the temporary auth key
2019-08-31 22:43:58 +02:00
*
* @ return bool
*/
public function hasAuthKey ( bool $temp = true ) : bool
{
2019-09-02 16:54:36 +02:00
return $this -> { $temp ? 'tempAuthKey' : 'permAuthKey' } !== null && $this -> { $temp ? 'tempAuthKey' : 'permAuthKey' } -> hasAuthKey ();
2019-08-31 22:43:58 +02:00
}
/**
* Set auth key .
*
2019-09-01 14:07:04 +02:00
* @ param AuthKey | null $key The auth key
2019-09-01 23:39:29 +02:00
* @ param boolean | null $temp Whether to set the temporary auth key
2019-08-31 22:43:58 +02:00
*
* @ return void
*/
2019-09-01 14:07:04 +02:00
public function setAuthKey ( ? AuthKey $key , bool $temp = true )
2019-08-31 22:43:58 +02:00
{
2019-09-02 16:54:36 +02:00
$this -> { $temp ? 'tempAuthKey' : 'permAuthKey' } = $key ;
2019-08-31 22:43:58 +02:00
}
2019-09-01 23:39:29 +02:00
/**
* Get temporary authorization key .
*
* @ return AuthKey
*/
public function getTempAuthKey () : TempAuthKey
{
return $this -> getAuthKey ( true );
}
/**
* Get permanent authorization key .
*
* @ return AuthKey
*/
public function getPermAuthKey () : PermAuthKey
{
return $this -> getAuthKey ( false );
}
/**
* Check if has temporary authorization key .
*
* @ return boolean
*/
public function hasTempAuthKey () : bool
{
return $this -> hasAuthKey ( true );
}
/**
* Check if has permanent authorization key .
*
* @ return boolean
*/
public function hasPermAuthKey () : bool
{
return $this -> hasAuthKey ( false );
}
/**
* Set temporary authorization key .
*
* @ param TempAuthKey | null $key Auth key
*
* @ return void
*/
public function setTempAuthKey ( ? TempAuthKey $key )
{
return $this -> setAuthKey ( $key , true );
}
/**
* Set permanent authorization key .
*
* @ param PermAuthKey | null $key Auth key
*
* @ return void
*/
public function setPermAuthKey ( ? PermAuthKey $key )
{
return $this -> setAuthKey ( $key , false );
}
/**
* Bind temporary and permanent auth keys .
*
* @ param bool $pfs Whether to bind using PFS
*
* @ return void
*/
public function bind ( bool $pfs = true )
{
2019-09-03 14:40:50 +02:00
if ( ! $pfs && ! $this -> tempAuthKey ) {
$this -> tempAuthKey = new TempAuthKey ();
}
2019-09-02 16:54:36 +02:00
$this -> tempAuthKey -> bind ( $this -> permAuthKey , $pfs );
2019-09-01 23:39:29 +02:00
}
2019-09-04 17:48:07 +02:00
/**
* Check if auth keys are bound .
*
* @ return boolean
*/
public function isBound () : bool
{
return $this -> tempAuthKey ? $this -> tempAuthKey -> isBound () : false ;
}
2019-08-31 22:43:58 +02:00
/**
* Check if we are logged in .
*
* @ return boolean
*/
public function isAuthorized () : bool
{
2019-09-01 23:39:29 +02:00
return $this -> hasTempAuthKey () ? $this -> getTempAuthKey () -> isAuthorized () : false ;
2019-08-31 22:43:58 +02:00
}
/**
* Set the authorized boolean .
*
* @ param boolean $authorized Whether we are authorized
*
* @ return void
*/
public function authorized ( bool $authorized )
{
2019-09-02 15:30:29 +02:00
if ( $authorized ) {
$this -> getTempAuthKey () -> authorized ( $authorized );
2019-09-02 16:54:36 +02:00
} elseif ( $this -> hasTempAuthKey ()) {
2019-09-02 15:30:29 +02:00
$this -> getTempAuthKey () -> authorized ( $authorized );
}
2019-09-01 23:39:29 +02:00
}
/**
* Link permanent authorization info of main DC to media DC .
*
* @ param string $dc Main DC ID
*
* @ return void
*/
public function link ( string $dc )
{
$this -> linked = $dc ;
2020-01-31 19:29:43 +01:00
$this -> permAuthKey =& $this -> API -> datacenter -> getDataCenterConnection ( $dc ) -> permAuthKey ;
2019-08-31 22:43:58 +02:00
}
2019-09-01 14:07:04 +02:00
/**
* Reset MTProto sessions .
*
* @ return void
*/
public function resetSession ()
{
foreach ( $this -> connections as $socket ) {
$socket -> resetSession ();
}
}
2019-09-02 16:54:36 +02:00
/**
2019-09-02 17:08:36 +02:00
* Create MTProto sessions if needed .
2019-09-02 16:54:36 +02:00
*
* @ return void
*/
public function createSession ()
{
foreach ( $this -> connections as $socket ) {
$socket -> createSession ();
}
}
2019-09-01 14:07:04 +02:00
/**
* Flush all pending packets .
*
* @ return void
*/
public function flush ()
{
foreach ( $this -> connections as $socket ) {
$socket -> flush ();
}
}
2019-08-31 22:43:58 +02:00
/**
2019-09-01 01:52:28 +02:00
* Get connection context .
2019-08-31 22:43:58 +02:00
*
* @ return ConnectionContext
*/
public function getCtx () : ConnectionContext
{
return $this -> ctx ;
}
2019-12-31 13:12:58 +01:00
/**
* Has connection context ?
*
* @ return bool
*/
public function hasCtx () : bool
{
return isset ( $this -> ctx );
}
2019-08-31 22:43:58 +02:00
/**
* Connect function .
*
* @ param ConnectionContext $ctx Connection context
2019-09-02 16:54:36 +02:00
* @ param int $id Optional connection ID to reconnect
2019-08-31 22:43:58 +02:00
*
* @ return \Generator
*/
2019-09-02 16:54:36 +02:00
public function connect ( ConnectionContext $ctx , int $id = - 1 ) : \Generator
2019-08-31 22:43:58 +02:00
{
2020-01-31 19:29:43 +01:00
$this -> API -> logger -> logger ( " Trying shared connection via { $ctx } ( { $id } ) " );
2019-08-31 22:43:58 +02:00
$this -> ctx = $ctx -> getCtx ();
$this -> datacenter = $ctx -> getDc ();
2019-09-02 16:54:36 +02:00
$media = $ctx -> isMedia () || $ctx -> isCDN ();
2020-09-22 11:48:12 +02:00
$count = $media ? $this -> API -> getSettings () -> getConnection () -> getMinMediaSocketCount () : 1 ;
2019-09-01 01:52:28 +02:00
if ( $count > 1 ) {
if ( ! $this -> robinLoop ) {
2020-09-22 11:48:12 +02:00
$this -> robinLoop = new PeriodicLoopInternal ( $this -> API , [ $this , 'even' ], " robin loop DC { $this -> datacenter } " , $this -> API -> getSettings () -> getConnection () -> getRobinPeriod () * 1000 );
2019-09-01 01:52:28 +02:00
}
$this -> robinLoop -> start ();
}
2019-09-02 16:54:36 +02:00
$this -> decRead = $media ? self :: READ_WEIGHT_MEDIA : self :: READ_WEIGHT ;
$this -> decWrite = self :: WRITE_WEIGHT ;
2019-12-29 13:20:18 +01:00
if ( $id === - 1 || ! isset ( $this -> connections [ $id ])) {
2019-09-03 19:03:39 +02:00
if ( $this -> connections ) {
2020-07-09 18:23:16 +02:00
$this -> API -> logger -> logger ( " Already connected! " , Logger :: WARNING );
2019-09-04 17:48:07 +02:00
return ;
2019-09-03 19:03:39 +02:00
}
2020-01-31 19:29:43 +01:00
yield from $this -> connectMore ( $count );
2019-09-04 17:48:07 +02:00
yield $this -> restoreBackup ();
2019-12-29 14:04:02 +01:00
$this -> connectionsPromise = new Success ();
if ( $this -> connectionsDeferred ) {
$connectionsDeferred = $this -> connectionsDeferred ;
$this -> connectionsDeferred = null ;
$connectionsDeferred -> resolve ();
}
2019-09-02 16:54:36 +02:00
} else {
2019-09-03 14:40:50 +02:00
$this -> availableConnections [ $id ] = 0 ;
2020-01-31 19:29:43 +01:00
yield from $this -> connections [ $id ] -> connect ( $ctx );
2019-09-02 16:54:36 +02:00
}
}
/**
2019-09-02 17:08:36 +02:00
* Connect to the DC using count more sockets .
2019-09-02 16:54:36 +02:00
*
* @ param integer $count Number of sockets to open
2019-09-02 17:08:36 +02:00
*
2020-10-01 20:48:22 +02:00
* @ return \Generator
2019-09-02 16:54:36 +02:00
*/
2020-01-31 19:29:43 +01:00
private function connectMore ( int $count ) : \Generator
2019-09-02 16:54:36 +02:00
{
$ctx = $this -> ctx -> getCtx ();
2019-09-02 17:08:36 +02:00
$count += $previousCount = \count ( $this -> connections );
2019-09-02 16:54:36 +02:00
for ( $x = $previousCount ; $x < $count ; $x ++ ) {
2019-10-28 17:08:04 +01:00
$connection = new Connection ();
$connection -> setExtra ( $this , $x );
2020-01-31 19:29:43 +01:00
yield from $connection -> connect ( $ctx );
2019-10-28 17:08:04 +01:00
$this -> connections [ $x ] = $connection ;
2019-09-01 01:52:28 +02:00
$this -> availableConnections [ $x ] = 0 ;
2019-08-31 22:43:58 +02:00
$ctx = $this -> ctx -> getCtx ();
}
}
2019-10-28 17:08:04 +01:00
/**
* Signal that a connection ID disconnected .
*
* @ param integer $id Connection ID
*
* @ return void
*/
public function signalDisconnect ( int $id )
{
$backup = $this -> connections [ $id ] -> backupSession ();
$list = '' ;
2020-01-03 16:47:57 +01:00
foreach ( $backup as $k => $message ) {
if (( $message [ '_' ] ? ? '' ) === 'msgs_state_req' ) {
unset ( $backup [ $k ]);
continue ;
}
2019-10-28 17:08:04 +01:00
$list .= $message [ '_' ] ? ? '-' ;
$list .= ', ' ;
}
2020-01-31 19:29:43 +01:00
$this -> API -> logger -> logger ( " Backed up { $list } from DC { $this -> datacenter } . { $id } " );
2019-10-28 17:08:04 +01:00
$this -> backup = \array_merge ( $this -> backup , $backup );
unset ( $this -> connections [ $id ], $this -> availableConnections [ $id ]);
}
2019-09-01 01:52:28 +02:00
/**
2019-09-01 14:07:04 +02:00
* Close all connections to DC .
2019-09-01 01:52:28 +02:00
*
* @ return void
*/
2020-02-28 14:14:02 +01:00
public function disconnect () : void
2019-08-31 22:43:58 +02:00
{
2020-01-31 19:29:43 +01:00
$this -> connectionsDeferred = new Deferred ();
2019-12-29 14:04:02 +01:00
$this -> connectionsPromise = $this -> connectionsDeferred -> promise ();
2019-09-01 01:52:28 +02:00
$this -> API -> logger -> logger ( " Disconnecting from shared DC { $this -> datacenter } " );
if ( $this -> robinLoop ) {
$this -> robinLoop -> signal ( true );
$this -> robinLoop = null ;
}
2019-09-12 18:56:26 +02:00
$before = \count ( $this -> backup );
2019-09-01 01:52:28 +02:00
foreach ( $this -> connections as $connection ) {
$connection -> disconnect ();
}
2019-09-12 18:56:26 +02:00
$count = \count ( $this -> backup ) - $before ;
2020-01-31 19:29:43 +01:00
$this -> API -> logger -> logger ( " Backed up { $count } , added to { $before } existing messages) from DC { $this -> datacenter } " );
2019-09-01 01:52:28 +02:00
$this -> connections = [];
$this -> availableConnections = [];
2019-08-31 22:43:58 +02:00
}
2019-09-01 01:52:28 +02:00
/**
2019-09-01 14:07:04 +02:00
* Reconnect to DC .
2019-09-01 01:52:28 +02:00
*
* @ return \Generator
*/
public function reconnect () : \Generator
2019-08-31 22:43:58 +02:00
{
2019-09-01 01:52:28 +02:00
$this -> API -> logger -> logger ( " Reconnecting shared DC { $this -> datacenter } " );
$this -> disconnect ();
2020-01-31 19:29:43 +01:00
yield from $this -> connect ( $this -> ctx );
2019-08-31 22:43:58 +02:00
}
2019-09-04 17:48:07 +02:00
/**
2019-09-12 18:56:26 +02:00
* Restore backed up messages .
2019-09-04 17:48:07 +02:00
*
* @ return void
*/
public function restoreBackup ()
{
$backup = $this -> backup ;
$this -> backup = [];
2019-09-12 18:56:26 +02:00
$count = \count ( $backup );
2020-01-31 19:29:43 +01:00
$this -> API -> logger -> logger ( " Restoring { $count } messages to DC { $this -> datacenter } " );
2019-09-04 17:48:07 +02:00
foreach ( $backup as $message ) {
2020-07-12 01:27:26 +02:00
if ( isset ( $message [ 'seqno' ])) {
unset ( $message [ 'seqno' ]);
}
if ( isset ( $message [ 'msg_id' ])) {
unset ( $message [ 'msg_id' ]);
}
2020-02-07 21:13:49 +01:00
if ( isset ( $message [ 'body' ])) {
Tools :: callFork ( $this -> getConnection () -> sendMessage ( $message , false ));
}
2019-09-04 17:48:07 +02:00
}
$this -> flush ();
}
2019-09-01 23:39:29 +02:00
/**
* Get connection for authorization .
*
* @ return Connection
*/
public function getAuthConnection () : Connection
{
return $this -> connections [ 0 ];
}
2019-09-17 21:35:53 +02:00
/**
* Check if any connection is available .
*
* @ param integer $id Connection ID
*
* @ return boolean
*/
public function hasConnection ( int $id = - 1 ) : bool
{
return $id < 0 ? \count ( $this -> connections ) : isset ( $this -> connections [ $id ]);
}
2019-12-29 14:04:02 +01:00
/**
* Get best socket in round robin , asynchronously .
*
2020-02-05 17:29:48 +01:00
* @ return \Generator < Connection >
2019-12-29 14:04:02 +01:00
*/
2020-02-05 17:29:48 +01:00
public function waitGetConnection () : \Generator
2019-12-29 14:04:02 +01:00
{
if ( empty ( $this -> availableConnections )) {
2020-02-05 17:29:48 +01:00
yield $this -> connectionsPromise ;
2019-12-29 14:04:02 +01:00
}
2020-02-05 17:29:48 +01:00
return $this -> getConnection ();
2019-12-29 14:04:02 +01:00
}
2019-09-01 01:52:28 +02:00
/**
* Get best socket in round robin .
*
2019-09-17 21:35:53 +02:00
* @ param integer $id Connection ID , for manual fetching
*
2019-09-01 01:52:28 +02:00
* @ return Connection
*/
2019-09-13 18:03:18 +02:00
public function getConnection ( int $id = - 1 ) : Connection
2019-08-31 22:43:58 +02:00
{
2019-09-13 18:03:18 +02:00
if ( $id >= 0 ) {
return $this -> connections [ $id ];
}
2019-09-02 15:30:29 +02:00
if ( \count ( $this -> availableConnections ) <= 1 ) {
2019-09-01 01:52:28 +02:00
return $this -> connections [ 0 ];
2019-08-31 22:43:58 +02:00
}
2019-09-02 16:54:36 +02:00
$max = \max ( $this -> availableConnections );
2019-09-02 17:08:36 +02:00
$key = \array_search ( $max , $this -> availableConnections );
2019-09-01 01:52:28 +02:00
// Decrease to implement round robin
$this -> availableConnections [ $key ] -- ;
return $this -> connections [ $key ];
2019-08-31 22:43:58 +02:00
}
2019-09-01 01:52:28 +02:00
/**
2019-09-01 14:07:04 +02:00
* Even out round robin values .
2019-09-01 01:52:28 +02:00
*
* @ return void
*/
public function even ()
2019-08-31 22:43:58 +02:00
{
2019-10-28 19:48:59 +01:00
if ( ! $this -> availableConnections ) {
return ;
}
2019-09-03 19:03:39 +02:00
$min = \min ( $this -> availableConnections );
if ( $min < 50 ) {
foreach ( $this -> availableConnections as & $count ) {
$count += 50 ;
}
2019-09-04 17:48:07 +02:00
} elseif ( $min < 100 ) {
2020-09-22 11:48:12 +02:00
$max = $this -> isMedia () || $this -> isCDN () ? $this -> API -> getSettings () -> getConnection () -> getMaxMediaSocketCount () : 1 ;
2019-09-02 16:54:36 +02:00
if ( \count ( $this -> availableConnections ) < $max ) {
$this -> connectMore ( 2 );
} else {
foreach ( $this -> availableConnections as & $value ) {
$value += 1000 ;
}
2019-09-01 01:52:28 +02:00
}
2019-08-31 22:43:58 +02:00
}
}
2019-09-02 14:37:30 +02:00
/**
* Indicate that one of the sockets is busy reading .
*
* @ param boolean $reading Whether we ' re busy reading
* @ param int $x Connection ID
*
* @ return void
*/
public function reading ( bool $reading , int $x )
{
$this -> availableConnections [ $x ] += $reading ? - $this -> decRead : $this -> decRead ;
}
/**
* Indicate that one of the sockets is busy writing .
*
* @ param boolean $writing Whether we ' re busy writing
* @ param int $x Connection ID
*
* @ return void
*/
public function writing ( bool $writing , int $x )
{
$this -> availableConnections [ $x ] += $writing ? - $this -> decWrite : $this -> decWrite ;
}
2019-09-01 01:52:28 +02:00
/**
2019-09-01 14:07:04 +02:00
* Set main instance .
2019-09-01 01:52:28 +02:00
*
* @ param MTProto $API Main instance
2019-09-01 14:07:04 +02:00
*
2019-09-01 01:52:28 +02:00
* @ return void
*/
2020-02-04 21:46:38 +01:00
public function setExtra ( $API )
2019-09-01 01:52:28 +02:00
{
$this -> API = $API ;
}
/**
2019-09-01 14:07:04 +02:00
* Get main instance .
2019-09-01 01:52:28 +02:00
*
* @ return MTProto
*/
2020-02-04 21:46:38 +01:00
public function getExtra ()
2019-09-01 01:52:28 +02:00
{
return $this -> API ;
}
2019-09-02 14:37:30 +02:00
/**
* Check if is an HTTP connection .
*
* @ return boolean
*/
2019-09-02 15:30:29 +02:00
public function isHttp () : bool
2019-09-02 14:37:30 +02:00
{
2020-09-22 11:48:12 +02:00
return \in_array ( $this -> ctx -> getStreamName (), [ HttpStream :: class , HttpsStream :: class ]);
2019-09-02 14:37:30 +02:00
}
2019-09-17 21:35:53 +02:00
/**
* Check if is connected directly by IP address .
*
* @ return boolean
*/
public function byIPAddress () : bool
{
2020-09-22 11:48:12 +02:00
return ! $this -> ctx -> hasStreamName ( WssStream :: class ) && ! $this -> ctx -> hasStreamName ( HttpsStream :: class );
2019-09-17 21:35:53 +02:00
}
2019-09-02 15:30:29 +02:00
/**
2019-09-02 16:54:36 +02:00
* Check if is a media connection .
2019-09-02 15:30:29 +02:00
*
* @ return boolean
*/
public function isMedia () : bool
{
return $this -> ctx -> isMedia ();
}
/**
2019-09-02 16:54:36 +02:00
* Check if is a CDN connection .
2019-09-02 15:30:29 +02:00
*
* @ return boolean
*/
public function isCDN () : bool
{
return $this -> ctx -> isCDN ();
}
2019-09-02 14:37:30 +02:00
/**
2019-09-02 16:54:36 +02:00
* Get DC - specific settings .
2019-09-02 14:37:30 +02:00
*
2020-09-22 11:48:12 +02:00
* @ return ConnectionSettings
*/
public function getSettings () : ConnectionSettings
{
return $this -> API -> getSettings () -> getConnection ();
}
/**
* Get global settings .
*
* @ return Settings
2019-09-02 14:37:30 +02:00
*/
2020-09-22 11:48:12 +02:00
public function getGenericSettings () : Settings
2019-09-02 14:37:30 +02:00
{
2020-09-22 11:48:12 +02:00
return $this -> API -> getSettings ();
2019-09-02 14:37:30 +02:00
}
2019-09-01 14:07:04 +02:00
/**
* JSON serialize function .
*
* @ return array
*/
public function jsonSerialize () : array
{
2020-01-31 19:29:43 +01:00
return $this -> linked ? [ 'linked' => $this -> linked , 'tempAuthKey' => $this -> tempAuthKey ] : [ 'permAuthKey' => $this -> permAuthKey , 'tempAuthKey' => $this -> tempAuthKey ];
2019-09-01 14:07:04 +02:00
}
2019-08-31 22:43:58 +02:00
/**
* Sleep function .
*
* @ internal
*
* @ return array
*/
public function __sleep ()
{
2019-09-02 16:54:36 +02:00
return $this -> linked ? [ 'linked' , 'tempAuthKey' ] : [ 'permAuthKey' , 'tempAuthKey' ];
2019-08-31 22:43:58 +02:00
}
}