- Symfony: 4.1
- PHP: 7.1
I have working websocket server using Ratchet. The websocket itself works fin. I can run it from the terminal using Symfony's commands
php bin/console app:websocket:execute
I'm having trouble getting around some of these issues:
- You need to dedicate a terminal to running this command
- Most webhosting services don't give you access to the terminal
- I want admins to be able to toggle the websocket server on and off
- Admins aren't required to know what a terminal is
For issue 1, I try to use this "detaching" cheat, but it doesn't solve issue 2:
php bin/console app:websocket:execute > /dev/null 2>&1 &
In order to tackle all four issues. I have tried using a process. but the issues with this approach is:
$process->run()
- running a process withphp bin/console
always ends in a timeout$process-start()
- starting a process means it runs asynchronously, but it also means the process is terminated once the request ends, terminating my websocket server too.
Here is an example
$process = new Process("php bin/console");
$process->setWorkingDirectory(getcwd() . "/../");
$process->setTimeout(10);
$process->run(); // Stalls for 10 seconds, then throws timeout exception
$process-start(); // Doesn't stall, but terminates at end of request
// $process->run() ==== unreachable code
if (!$process->isSuccessful()) {
throw new ProcessFailedException($process);
}
I have tried creating a console application, and run the command from there. but the same issues as a process apply here.
$application = new Application($this->kernel);
$application->setAutoExit(false);
$input = new ArrayInput(array(
'command' => 'app:websocket:execute'
));
try {
$ob = new BufferedOutput();
$application->run($input, $ob);
$output = $ob->fetch();
} catch (\Exception $e) {
return null;
}
As a final resort, I tried a bundle called DtcQueueBundle, because it mentions the following:
Ease of Use
- Kickoff background tasks with a line of code or two
- Easily add background worker services
- Turn any code into background task with a few lines
So I did what they asked, created a worker and tried to run it as a "background task"
use App\Ratchet\ForumUpdater;
use Ratchet\Http\HttpServer;
use Ratchet\Server\IoServer;
use Ratchet\WebSocket\WsServer;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class SocketWorker extends \Dtc\QueueBundle\Model\Worker
{
public function execute()
{
$server = IoServer::factory(
new HttpServer(
new WsServer(
new ForumUpdater()
)
),
8080
);
$server->run();
return "Websocket started";
}
public function getName()
{
return "websocket-server";
}
}
Their docs are the absolute worst! I even tried to dig into their code to start jobs from inside my controller. But I couldn't get it to run in a detached manner.
Whatever happens, I believe my command isn't running because it highjacks my PHP thread. I would like to know, is it possible to detach this endless process? Is it even possible to run two PHP instances together? I would think so!
Thanks for any help, sorry for the long post
exec
,shell_exec
,proc_open
and things like that. I was hoping that would do the trick somehow – Blane> /dev/null 2>&1 &
doesn't work. All processes in my terminal session are terminated once the user's request ends. This includes subshells. – BlaneMost webhosting services don't give you access to the terminal
. good to know though! – Blane