Improvements to socket interface and TL parser

This commit is contained in:
Daniil Gentili 2018-03-05 15:57:35 +01:00
parent e9dc0ba6f6
commit a2255fa7ad
5 changed files with 19 additions and 16 deletions

View File

@ -2,5 +2,5 @@
require 'vendor/autoload.php'; require 'vendor/autoload.php';
$handler = new \danog\MadelineProto\Server(['type' => AF_INET, 'protocol' => 0, 'address' => 'localhost', 'port' => 8005]); $handler = new \danog\MadelineProto\Server(['type' => AF_INET, 'protocol' => 0, 'address' => 'localhost', 'port' => 8009]);
$handler->start(); $handler->start();

View File

@ -166,7 +166,6 @@ class Connection
throw new Exception(\danog\MadelineProto\Lang::$current_lang['protocol_not_implemented']); throw new Exception(\danog\MadelineProto\Lang::$current_lang['protocol_not_implemented']);
default: default:
throw new Exception(\danog\MadelineProto\Lang::$current_lang['protocol_invalid']); throw new Exception(\danog\MadelineProto\Lang::$current_lang['protocol_invalid']);
break;
} }
} }
@ -188,7 +187,6 @@ class Connection
throw new Exception(\danog\MadelineProto\Lang::$current_lang['protocol_not_implemented']); throw new Exception(\danog\MadelineProto\Lang::$current_lang['protocol_not_implemented']);
default: default:
throw new Exception(\danog\MadelineProto\Lang::$current_lang['protocol_invalid']); throw new Exception(\danog\MadelineProto\Lang::$current_lang['protocol_invalid']);
break;
} }
} }
@ -275,7 +273,6 @@ class Connection
throw new Exception(\danog\MadelineProto\Lang::$current_lang['protocol_not_implemented']); throw new Exception(\danog\MadelineProto\Lang::$current_lang['protocol_not_implemented']);
default: default:
throw new Exception(\danog\MadelineProto\Lang::$current_lang['protocol_invalid']); throw new Exception(\danog\MadelineProto\Lang::$current_lang['protocol_invalid']);
break;
} }
} }
@ -322,6 +319,8 @@ class Connection
return $response['body']; return $response['body'];
case 'udp': case 'udp':
throw new Exception(\danog\MadelineProto\Lang::$current_lang['protocol_not_implemented']); throw new Exception(\danog\MadelineProto\Lang::$current_lang['protocol_not_implemented']);
default:
throw new Exception(\danog\MadelineProto\Lang::$current_lang['protocol_invalid']);
} }
} }
@ -358,7 +357,7 @@ class Connection
case 'udp': case 'udp':
throw new Exception(\danog\MadelineProto\Lang::$current_lang['protocol_not_implemented']); throw new Exception(\danog\MadelineProto\Lang::$current_lang['protocol_not_implemented']);
default: default:
break; throw new Exception(\danog\MadelineProto\Lang::$current_lang['protocol_invalid']);
} }
} }

View File

@ -20,12 +20,13 @@ class Server
{ {
private $settings; private $settings;
private $pids = []; private $pids = [];
private $mypid;
public function __construct($settings) public function __construct($settings)
{ {
set_error_handler(['\\danog\\MadelineProto\\Exception', 'ExceptionErrorHandler']); set_error_handler(['\\danog\\MadelineProto\\Exception', 'ExceptionErrorHandler']);
$this->settings = $settings; $this->settings = $settings;
$this->main = getmypid(); $this->mypid = getmypid();
} }
public function start() public function start()
@ -47,7 +48,7 @@ class Server
try { try {
if ($sock = $this->sock->accept()) { if ($sock = $this->sock->accept()) {
$this->handle($sock); $this->handle($sock);
} }
} catch (\danog\MadelineProto\Exception $e) { } catch (\danog\MadelineProto\Exception $e) {
} }
} }
@ -67,14 +68,16 @@ class Server
public function __destruct() public function __destruct()
{ {
if (!\danog\MadelineProto\Logger::$is_fork) { if ($this->mypid === getmypid()) {
\danog\MadelineProto\Logger::log('Shutting main process down'); \danog\MadelineProto\Logger::log('Shutting main process '.$this->mypid.' down');
unset($this->sock);
foreach ($this->pids as $pid) { foreach ($this->pids as $pid) {
\danog\MadelineProto\Logger::log("Waiting for $pid");
pcntl_wait($pid); pcntl_wait($pid);
} }
\danog\MadelineProto\Logger::log("Done, closing main process");
return; return;
} }
\danog\MadelineProto\Logger::log('Shutting fork '.getmypid().' down');
} }
public function sig_handler($sig) public function sig_handler($sig)
@ -82,7 +85,6 @@ class Server
switch ($sig) { switch ($sig) {
case SIGTERM: case SIGTERM:
case SIGINT: case SIGINT:
Logger::log('Got SIGTERM/SIGINT in '.getmypid());
exit(); exit();
case SIGCHLD: case SIGCHLD:

View File

@ -26,10 +26,14 @@ class Handler extends \danog\MadelineProto\Connection
{ {
$this->sock = $socket; $this->sock = $socket;
$this->sock->setBlocking(true); $this->sock->setBlocking(true);
$this->protocol = $protocol; $timeout = 2;
$this->sock->setOption(\SOL_SOCKET, \SO_RCVTIMEO, $timeout);
$this->sock->setOption(\SOL_SOCKET, \SO_SNDTIMEO, $timeout);
$this->protocol = $extra;
$this->construct_TL(['socket' => __DIR__.'/../TL_socket.tl']); $this->construct_TL(['socket' => __DIR__.'/../TL_socket.tl']);
} }
public function __destruct() { public function __destruct() {
\danog\MadelineProto\Logger::log('Closing socket in fork '.getmypid());
unset($this->sock); unset($this->sock);
$this->destruct_madeline(); $this->destruct_madeline();
exit(); exit();
@ -46,15 +50,13 @@ class Handler extends \danog\MadelineProto\Connection
public function loop() public function loop()
{ {
while (true) { while (true) {
pcntl_signal_dispatch();
$request_id = 0; $request_id = 0;
try { try {
$message = $this->read_message(); $message = $this->read_message();
} catch (\danog\MadelineProto\NothingInTheSocketException $e) { } catch (\danog\MadelineProto\NothingInTheSocketException $e) {
continue; continue;
} }
if ($message === null) {
continue;
}
try { try {
$message = $this->deserialize($message, ['type' => '', 'datacenter' => '']); $message = $this->deserialize($message, ['type' => '', 'datacenter' => '']);
if ($message['_'] !== 'socketMessageRequest') { if ($message['_'] !== 'socketMessageRequest') {

View File

@ -101,7 +101,7 @@ trait TL
} }
$clean = preg_replace(['/:bytes /', '/;/', '/#[a-f0-9]+ /', '/ [a-zA-Z0-9_]+\\:flags\\.[0-9]+\\?true/', '/[<]/', '/[>]/', '/ /', '/^ /', '/ $/', '/\\?bytes /', '/{/', '/}/'], [':string ', '', ' ', '', ' ', ' ', ' ', '', '', '?string ', '', ''], $line); $clean = preg_replace(['/:bytes /', '/;/', '/#[a-f0-9]+ /', '/ [a-zA-Z0-9_]+\\:flags\\.[0-9]+\\?true/', '/[<]/', '/[>]/', '/ /', '/^ /', '/ $/', '/\\?bytes /', '/{/', '/}/'], [':string ', '', ' ', '', ' ', ' ', ' ', '', '', '?string ', '', ''], $line);
$id = hash('crc32b', $clean); $id = hash('crc32b', $clean);
if (preg_match('/^[^#]+#([a-f0-9]*)/i', $line, $matches)) { if (preg_match('/^[^\s]+#([a-f0-9]*)/i', $line, $matches)) {
$nid = str_pad($matches[1], 8, '0', \STR_PAD_LEFT); $nid = str_pad($matches[1], 8, '0', \STR_PAD_LEFT);
if ($id !== $nid && $scheme_type !== 'botAPI') { if ($id !== $nid && $scheme_type !== 'botAPI') {
\danog\MadelineProto\Logger::log(sprintf(\danog\MadelineProto\Lang::$current_lang['crc32_mismatch'], $id, $nid, $line), \danog\MadelineProto\Logger::ERROR); \danog\MadelineProto\Logger::log(sprintf(\danog\MadelineProto\Lang::$current_lang['crc32_mismatch'], $id, $nid, $line), \danog\MadelineProto\Logger::ERROR);