Closed Sebbo94BY closed 1 year ago
When I change in the while (true)
endless loop to the emit()
instead of the wait()
function, everything works as expected:
<?php
namespace App\Console\Commands;
use App\Models\Instance;
use Illuminate\Console\Command;
use PlanetTeamSpeak\TeamSpeak3Framework\Adapter\ServerQuery;
use PlanetTeamSpeak\TeamSpeak3Framework\Exception\ServerQueryException;
use PlanetTeamSpeak\TeamSpeak3Framework\Exception\TransportException;
use PlanetTeamSpeak\TeamSpeak3Framework\Helper\Signal;
use PlanetTeamSpeak\TeamSpeak3Framework\TeamSpeak3;
class StartBot extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'bot:start';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Starts a TeamSpeak bot.';
/**
* Callback method for 'serverqueryWaitTimeout' signals.
*
* @param integer $seconds
* @return void
*/
public static function onWaitTimeout(int $idle_seconds, ServerQuery $serverquery)
{
// This is mostly for debug, you do not need. Remove if you do not want extra messages filling up screen.
// Every 20 seconds, print 'seconds since last event or msg from server'
if ($idle_seconds % 10 == 0) {
echo "No reply from the server for $idle_seconds seconds\n";
}
// If the timestamp on the last query is more than 300 seconds (5 minutes) in the past, send 'keepalive'
// 'keepalive' command is just server query command 'clientupdate' which does nothing without properties. So nothing is changes.
if($serverquery->getQueryLastTimestamp() < time()-250)
{
echo "Sending keep-alive\n";
$serverquery->request("clientupdate");
}
}
/**
* Starts the bot.
*/
public function start_bot(Instance $instance)
{
$this->info("Starting TeamSpeak bot instance: ".$instance->voice_port);
$TS3PHPFramework = new TeamSpeak3();
$connection_uri = "serverquery://$instance->serverquery_username:$instance->serverquery_password@$instance->host:$instance->serverquery_port/?server_port=$instance->voice_port&nickname=$instance->client_nickname&ssh=1&blocking=0";
try {
$virtualserver = $TS3PHPFramework->factory($connection_uri);
} catch (TransportException $e) {
throw new TransportException($e->getMessage(), $e->getCode());
}
if (! is_null($instance->default_channel_id)) {
try {
$virtualserver->clientMove($virtualserver->whoamiGet("client_id"), $instance->default_channel_id);
} catch (ServerQueryException $e) {
throw new ServerQueryException($e->getMessage(), $e->getCode());
}
}
// register a callback for serverqueryWaitTimeout events
Signal::getInstance()->subscribe("serverqueryWaitTimeout", [__CLASS__, 'onWaitTimeout']);
// wait for events
while (true) {
Signal::getInstance()->emit("serverqueryWaitTimeout", [time()-$virtualserver->getAdapter()->getQueryLastTimestamp(), $virtualserver->getAdapter()]);
sleep(5);
}
}
/**
* Execute the console command.
*/
public function handle(): void
{
$instance = Instance::all()->first();
try {
$this->start_bot($instance);
} catch (TransportException $transport_exception) {
$this->error($transport_exception->getMessage());
}
}
}
The callback is called, the keep-alive sent and the client stays connected:
www-data@e33647dcf607:~$ php artisan bot:start
Starting TeamSpeak bot instance: 9987
No reply from the server for 0 seconds
No reply from the server for 10 seconds
No reply from the server for 20 seconds
No reply from the server for 30 seconds
No reply from the server for 40 seconds
No reply from the server for 50 seconds
No reply from the server for 60 seconds
No reply from the server for 70 seconds
No reply from the server for 80 seconds
No reply from the server for 90 seconds
No reply from the server for 100 seconds
No reply from the server for 110 seconds
No reply from the server for 120 seconds
No reply from the server for 130 seconds
No reply from the server for 140 seconds
No reply from the server for 150 seconds
No reply from the server for 160 seconds
No reply from the server for 170 seconds
No reply from the server for 180 seconds
No reply from the server for 190 seconds
No reply from the server for 200 seconds
No reply from the server for 210 seconds
No reply from the server for 220 seconds
No reply from the server for 230 seconds
No reply from the server for 240 seconds
No reply from the server for 250 seconds
Sending keep-alive
No reply from the server for 10 seconds
No reply from the server for 20 seconds
No reply from the server for 30 seconds
No reply from the server for 40 seconds
No reply from the server for 50 seconds
No reply from the server for 60 seconds
No reply from the server for 70 seconds
No reply from the server for 80 seconds
No reply from the server for 90 seconds
No reply from the server for 100 seconds
No reply from the server for 110 seconds
No reply from the server for 120 seconds
No reply from the server for 130 seconds
No reply from the server for 140 seconds
No reply from the server for 150 seconds
No reply from the server for 160 seconds
No reply from the server for 170 seconds
No reply from the server for 180 seconds
No reply from the server for 190 seconds
No reply from the server for 200 seconds
No reply from the server for 210 seconds
No reply from the server for 220 seconds
No reply from the server for 230 seconds
No reply from the server for 240 seconds
No reply from the server for 250 seconds
Sending keep-alive
No reply from the server for 10 seconds
...
When I var_dump()
at vendor\planetteamspeak\ts3-php-framework\src\Adapter\ServerQuery.php:L165
within the wait()
function before the do-while
loop this: var_dump($this->getTransport());
, it returns the following for me:
object(PlanetTeamSpeak\TeamSpeak3Framework\Transport\TCP)#1599 (4) {
["config":protected]=>
array(8) {
["host"]=>
object(PlanetTeamSpeak\TeamSpeak3Framework\Helper\StringHelper)#1596 (2) {
["string":protected]=>
string(14) "localhost"
["position":protected]=>
int(0)
}
["port"]=>
int(10022)
["timeout"]=>
int(10)
["blocking"]=>
int(0)
["tls"]=>
int(0)
["ssh"]=>
int(1)
["username"]=>
object(PlanetTeamSpeak\TeamSpeak3Framework\Helper\StringHelper)#1595 (2) {
["string":protected]=>
string(11) "serveradmin"
["position":protected]=>
int(0)
}
["password"]=>
object(PlanetTeamSpeak\TeamSpeak3Framework\Helper\StringHelper)#1597 (2) {
["string":protected]=>
string(22) "censoredPassword"
["position":protected]=>
int(0)
}
}
["stream":protected]=>
resource(653) of type (stream)
["session":protected]=>
resource(652) of type (SSH2 Session)
["adapter":protected]=>
object(PlanetTeamSpeak\TeamSpeak3Framework\Adapter\ServerQuery)#1598 (6) {
["options":protected]=>
array(8) {
["host"]=>
object(PlanetTeamSpeak\TeamSpeak3Framework\Helper\StringHelper)#1596 (2) {
["string":protected]=>
string(14) "localhost"
["position":protected]=>
int(0)
}
["port"]=>
int(10022)
["timeout"]=>
int(10)
["blocking"]=>
int(0)
["tls"]=>
int(0)
["ssh"]=>
int(1)
["username"]=>
object(PlanetTeamSpeak\TeamSpeak3Framework\Helper\StringHelper)#1595 (2) {
["string":protected]=>
string(11) "serveradmin"
["position":protected]=>
int(0)
}
["password"]=>
object(PlanetTeamSpeak\TeamSpeak3Framework\Helper\StringHelper)#1597 (2) {
["string":protected]=>
string(22) "censoredPassword"
["position":protected]=>
int(0)
}
}
["transport":protected]=>
*RECURSION*
["host":protected]=>
object(PlanetTeamSpeak\TeamSpeak3Framework\Node\Host)#1601 (16) {
["parent":protected]=>
*RECURSION*
["server":protected]=>
NULL
["nodeId":protected]=>
int(0)
["nodeList":protected]=>
NULL
["nodeInfo":protected]=>
array(0) {
}
["storage":protected]=>
array(4) {
["_login_user"]=>
string(11) "serveradmin"
["_login_pass"]=>
string(32) "otherCensoredPassword"
["_query_nick"]=>
string(6) "MyNickname"
["_server_use"]=>
array(2) {
[0]=>
string(18) "serverSelectByPort"
[1]=>
array(1) {
[0]=>
int(9987)
}
}
}
["whoami":protected]=>
array(11) {
["virtualserver_status"]=>
object(PlanetTeamSpeak\TeamSpeak3Framework\Helper\StringHelper)#1626 (2) {
["string":protected]=>
string(6) "online"
["position":protected]=>
int(0)
}
["virtualserver_id"]=>
int(6)
["virtualserver_unique_identifier"]=>
object(PlanetTeamSpeak\TeamSpeak3Framework\Helper\StringHelper)#1629 (2) {
["string":protected]=>
string(28) "81vRlqHnHctHQMj/EKnztIgn/fU="
["position":protected]=>
int(0)
}
["virtualserver_port"]=>
int(9987)
["client_id"]=>
int(804)
["client_channel_id"]=>
int(147)
["client_nickname"]=>
object(PlanetTeamSpeak\TeamSpeak3Framework\Helper\StringHelper)#1616 (2) {
["string":protected]=>
string(6) "MyNickname"
["position":protected]=>
int(0)
}
["client_database_id"]=>
int(1)
["client_login_name"]=>
object(PlanetTeamSpeak\TeamSpeak3Framework\Helper\StringHelper)#1631 (2) {
["string":protected]=>
string(11) "serveradmin"
["position":protected]=>
int(0)
}
["client_unique_identifier"]=>
object(PlanetTeamSpeak\TeamSpeak3Framework\Helper\StringHelper)#1628 (2) {
["string":protected]=>
string(11) "serveradmin"
["position":protected]=>
int(0)
}
["client_origin_server_id"]=>
int(0)
}
["version":protected]=>
NULL
["serverList":protected]=>
NULL
["permissionEnds":protected]=>
NULL
["permissionList":protected]=>
NULL
["permissionCats":protected]=>
NULL
["predefined_query_name":protected]=>
string(6) "MyNickname"
["exclude_query_clients":protected]=>
bool(false)
["start_offline_virtual":protected]=>
bool(false)
["sort_clients_channels":protected]=>
bool(false)
}
["timer":protected]=>
int(1678151488)
["count":protected]=>
int(4)
["block":protected]=>
array(1) {
[0]=>
string(4) "help"
}
}
}
And at the same line, var_dump($this->getTransport()->readLine());
returns absolutely nothing.
...thus var_dump($evt->section(TeamSpeak3::SEPARATOR_CELL)->startsWith(TeamSpeak3::EVENT));
in the wait()
function returns Undefined variable $evt
.
There were one change regarding PHP 8 support in this function:
- } while ($evt instanceof StringHelper && !$evt->section(TeamSpeak3::SEPARATOR_CELL)->startsWith(TeamSpeak3::EVENT));
+ } while (!$evt->section(TeamSpeak3::SEPARATOR_CELL)->startsWith(TeamSpeak3::EVENT));
But besides this, I didn't found any other relevant changes, which could cause this behaviour. However, changing this line back also doesn't fix it.
@ronindesign Can you reproduce this issue? Is it a problem of this project or my code? 😅
Yes, there is actually a bug in the code of this project. I've fixed it and also added some PHPUnit tests for the future.: https://github.com/planetteamspeak/ts3phpframework/pull/190 :)
Hey,
I'm currently trying to get a bot connected, but it always looses the connection to the server, although I've configured the known keep-alive logic. It seems like as the keep-alive callback function never gets executed, because I don't see any debug messages during the entire 5 minutes until the timeout occurs.
Calling a different function within the same class works fine (see my below code and the execution).
The plan is to keep the client connected forever (until I kill the PHP process), regulary run specific ServerQuery commands and in case of clients joined or left, the ServerQuery commands should also get executed.
My Environment:
My code:
As you can see in the below output: I never see the
onWaitTimeout triggered
text, which should get always printed, when the callback gets triggered.Exception:
The client connects as expected, but after exactly 300 seconds, the timeout kicks in and the clients looses the connection.
Can anyone see an issue in my code or is it an issue of this project? I ran out of ideas. :(