Хорошо, это моя большая проблема, и я потратил более часа на создание рабочего примера, поэтому я надеюсь, что кто-то там сможет достаточно посочувствовать моей проблеме, чтобы дать некоторую помощь или обратную связь.
Я готов предоставить вам доступ bash к системе centos с php 5.4, чтобы вы могли самостоятельно протестировать код, и я даже приглашаю вас в группу телеграмм «Тестовый чат», чтобы вы могли сами увидеть результаты. Если вы принимаете пожертвования, я готов пожертвовать $$$$$$, просто назовите вашу цену.
Вот сценарий:
Я управляю коммуникационным ботом, который подключается к irc и telegram. По идее люди типа! Uptime в чате на канале (#public
на irc.glx-alliance.com:6668
) и в группе Telegram test chat
и бот сообщает им, как долго они были в сети. Пример работает, и IRC, и TG возвращают статистику времени работы по запросу через !uptime
команда. Все идет нормально.
Вот проблема:
Когда я печатаю !uptime
в клиенте IRC я получаю супер быстрое время отклика 0,02 секунды. Отлично. Это работает. Однако для интеграции Telegram, !uptime
Ответ может занять до 30 секунд. Причина почему ниже.
Еще несколько деталей:
Инициатор ответа Telegram не в том, что цикл проверяется очень медленно, а в том, что IRC отправил данные в соединение IRC. Который затем предлагает запустить код телеграммы. Я могу легко воспроизвести это, просто набрав в чате канал, и сразу же канал тестового чата Telegram получит ответ о доступности.
Вот мой рабочий пример. Чтобы это работало, вам нужно будет открыть порт 6668
в вашем брандмауэре есть telegram-cli
установить и запустить его из каталога с установленным telegram-cli-php. Увидеть https://github.com/zyberspace/php-telegram-cli-client. Просто наберите composer require zyberspace/telegram-cli-client
в каталоге проекта и создайте telegramIntegrations.php
файл в includes
каталог с вызовом vendor.php там. (require('vendor/autoload.php');
). Мой номер телефона +447935499706 добавь мне телеграмму и я приглашаю тебя на test chat
группа.
Вот код Если не считать игры код гольф Я не могу уменьшить размер файла дальше. Я опишу важные биты после самого кода.
<?php
set_time_limit(0);
ini_set('display_errors', 'on');
global $configure;
$configure = array(
'server' => 'irc.glx-alliance.com',
'port' => 6668,
'nick' => 'ExampleBot',
'name' => 'Example Bot'
);
include_once('../includes/telegramIntegration.php');
class IRCBot{
// TCP connection holder.
public $socket;
// Message holder.
public $msg = array();
/*
* Constucter.
* Opens the server connection, and logs in the bot.
*
* @param array.
*/
function __construct($configure){
echo '-----------Socket opening...----------------------------------' ."\r\n";
$this->socket = fsockopen($configure['server'], $configure['port']);
$this->login($configure);
$this->timestamp = time();
$this->main();
}
/*
* Logs bot in to server
*
* @param array.
*/
function login ($configure){
$this->send_data('USER', $configure['nick'] . ' rogues-alliance.com ' . $configure['nick'] . ' :' . $configure['name']);
$this->send_data('NICK', $configure['nick']);
}
/*
* Startup commands
*/
function startup () {
echo 'Startup initiated...' . PHP_EOL;
echo 'Startup finished' . PHP_EOL;
}
/*
* Bot Command
*/
function intel () {
return $this->intel;
}
/*
* Main function, used to grab all data.
*/
function main(){
while (true):
/* Fetch Data From Telegram Socket */
$this->telegram = new \Zyberspace\Telegram\Cli\Client('unix:///tmp/tg.sck');/* Fetch Data From IRC Socket */
$data = fgets($this->socket, 1024);
flush();
$data = preg_replace('/\s{2,}/ ', ' ', $data) . PHP_EOL;
$this->ex = explode(' ', $data);
/* Ping Pong */
if($this->ex[0] == 'PING'):
$this->send_data('PONG', $this->ex[1]);
endif;
/* Internal While Loops */
if (!$this->firstRun) {
$this->firstRun = true;
// do some stuff
}
if ($this->inited){ // have we had the server motd etc
}
/* Format Text */
$command = str_replace(array(chr(10), chr(13)), '', $this->ex[3]);
if (strtoupper($this->ex[1]) == $this->ex[1]):
$request = $this->ex[1];
endif;/* Handle Text from IRC $data */
switch ($request):
case 'PRIVMSG':
/* Setup Variables */
$host = $this->ex[0];
$username = substr($host, 1, strpos($host, '!')-1);
$target = $this->ex[2];
// list of commands the bot responds to
switch ($command){
case ':!uptime':
$this->sendMessage($this->uptime());
break;
break;
case ':!help':
$this->sendMessage('Available commands: !uptime', $this->ex[2]);
break;
}
break;
case '372':
case '375':
case '265':
case '255':
case '254':
case '003':
case '002':
echo $text;
break;
case '376':
/* Startup Commands */
$this->startup();
break;
case 'QUIT':
break;
default:
endswitch;
/* Handle Text From Telegram $telegram */
if (!$channels)
$channels = array(
'test chat'
);
foreach ($channels as $channel):
if (!$this->_tgData[$channel]):
$this->_tgData[$channel] = $this->telegram->getHistory($channel, 1);
$this->_tgData[$channel] = substr($this->_tgData[$channel], strpos($this->_tgData[$channel], ']')+3);
endif;
// fetch data
$this->_history[$channel] = $this->telegram->getHistory($channel, 1, 0);
$this->_history[$channel] = substr($this->_history[$channel], strpos($this->_history[$channel], ']')+3);
flush();
$b=0;
$output = array();
while (str_replace('>>>' , '', str_replace('»»»', '', str_replace('«««', '', str_replace('<<<', '', $this->_tgData[$channel])))) != str_replace('>>>' , '', str_replace('»»»', '', str_replace('«««', '', str_replace('<<<', '', $this->_history[$channel]))))):
// fetch data
$this->_history[$channel] = $this->telegram->getHistory($channel, 1, $b);
$this->_history[$channel] = substr($this->_history[$channel], strpos($this->_history[$channel], ']')+3);
flush();
if (preg_match("/(.+) [«><»]{3} (![\w\d]+) (.+)/", $this->_history[$channel], $matches)):
$username = substr(str_replace($channel, '', $matches[1]), 1);
$command = $matches[2];
$tokens = explode(' ', $matches[3]);
switch($command):
case '!uptime':
echo 'got here';
$this->telegram->msg($channel, $this->uptime());
endswitch;
endif;
$b++;
endwhile;
endforeach;
endwhile;
}
function sendMessage ($message, $to = false){
$this->send_data("PRIVMSG", (!$to?$this->ex[2]:$to) . " :" . $message);
}
/*
* Sends data to the server.
*/
function send_data($cmd, $msg = null){
if($msg == null){
fputs($this->socket, $cmd . "\n");
} else {
fputs($this->socket, $cmd.' '.$msg."\n");
}
}
function uptime () {
echo '------time-----';
$days = round((time() - $this->timestamp)/60/60/24);
$hours = round((time() - $this->timestamp)/60/60%24);
$minutes = round((time() - $this->timestamp)/60%60);
echo $this->timestamp;
echo '---time----';
return "I have been online for $days days, $hours hours and $minutes minutes";
}
}
$bot = new IRCBot($configure);
?>
Итак, важными частями кода являются следующие:
while (true): /*code*/ endwhile;
/* Fetch Data From Telegram Socket */
$this->telegram = new \Zyberspace\Telegram\Cli\Client('unix:///tmp/tg.sck');
/* Fetch Data From IRC Socket */
$data = fgets($this->socket, 1024);
flush();
Данные извлекаются из сокета IRC и сокета Telegram, но сокет IRC получает данные в этот момент, Telegram должен сделать дополнительный вызов для получения данных. Увидеть ниже.
$this->_tgData[$channel] = $this->telegram->getHistory($channel, 1);
$this->_tgData[$channel] = substr($this->_tgData[$channel], strpos($this->_tgData[$channel], ']')+3);
Telegram собирает свои данные здесь.
Так что это охватывает все, что я могу придумать. Я буду использовать функцию «показать этот вопрос другу», поэтому, пожалуйста, не пишите о том, как много кода; Я объяснил соответствующие части, поэтому, пожалуйста, будьте спокойны. Кроме того, код не может быть короче, если я попробую. Это полный пример, и я готов предложить вам среду для тестирования, для которой я пожертвую вам или благотворительную организацию по вашему выбору.
Также обратите внимание: кто-то может создать теги telegram-cli и telegram-cli-php, оба являются очень полезными проектами для сообщества.
Задача ещё не решена.
Других решений пока нет …