好的,这是我的一个大问题,我已经花了一个多小时创建一个工作示例,所以我希望那里的人能够对我的问题足够同情以提供一些帮助或反馈。我准备让你 bash 访问运行 php 5.4 的 centos 系统,这样你就可以自己测试代码,我什至会邀请你加入电报组“测试聊天”,这样你就可以自己查看结果。如果您接受捐赠,我准备捐赠 $$$$$$,只需说出您的价格。
这是场景:我正在运行一个连接到 irc 和电报的通信机器人。这个想法是人们在聊天频道(#public
on irc.glx-alliance.com:6668
)和 Telegram 组中输入 !uptime,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,它们都是对社区非常有用的项目。