Skip to content

Instantly share code, notes, and snippets.

@J7mbo
Forked from DaveRandom/HandlerManager.php
Created October 4, 2013 15:49
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save J7mbo/6828111 to your computer and use it in GitHub Desktop.
<?php
namespace Seedstream;
use React\EventLoop\LoopInterface,
React\Socket\ConnectionInterface;
class HandlerManager
{
private $loop;
private $handlerFactory;
private $clients;
public function __construct(LoopInterface $loop, TorrentHandlerFactory $handlerFactory)
{
$this->loop = $loop;
$this->handlerFactory = $handlerFactory;
}
public function onSubscribe(ConnectionInterface $conn, $subscription)
{
$handler = $this->handlerFactory->create();
$handler->onNotification($this->loop, function($data) use($subscription) {
$subscription->broadcast($data);
});
// store the handler instance somewhere so it can be made available when the
// client asks for something to do done (add/start/stop torrent etc)
}
}
<?php
namespace Seedstream;
class Torrent
{
private $dispatcher;
private $id;
// etc
public function __construct(TorrentActionDispatcher $dispatcher = null)
{
if ($dispatcher) {
$this->dispatcher = $dispatcher;
}
}
public function setDispatcher(TorrentActionDispatcher $dispatcher)
{
if (!$this->dispatcher) {
$this->dispatcher = $dispatcher;
}
}
public function setId($id)
{
$this->id = $id;
}
public function getId()
{
return $this->id;
}
// etc
public function start()
{
$this->dispatcher->start($this);
}
public function stop()
{
$this->dispatcher->stop($this);
}
public function getInfo()
{
$this->dispatcher->getInfo($this);
}
}
<?php
namespace Seedstream;
class TorrentFactory
{
public function create(TorrentActionDispatcher $dispatcher = null)
{
return new Torrent($dispatcher);
}
}
<?php
namespace Seedstream;
use React\EventLoop\LoopInterface;
interface TorrentHandler
{
public function addTorrent(Torrent $torrent);
public function removeTorrent(Torrent $torrent);
public function getTorrentById($id);
public function onNotification(LoopInterface $loop, callable $callback);
}
<?php
namespace Seedstream;
interface TorrentHandlerFactory
{
public function create();
}
<?php
// config
$execPath = '/usr/bin/transmission';
$bindAddr = '0.0.0.0';
$bindPort = 8080;
$loop = React\EventLoop\Factory::create();
$handlerFactory = new Seedstream\Transmission\HandlerFactory(
new Seedstream\Transmission\TorrentBuilder(new Seedstream\TorrentFactory),
new Seedstream\Transmission\ActionDispatcher($execPath);
);
$manager = new Seedstream\HandlerManager($loop, $handlerFactory);
$webSock = new React\Socket\Server($loop);
$webSock->listen($bindPort, $bindAddr);
$webServer = new Ratchet\Server\IoServer(
new Ratchet\WebSocket\WsServer(
new Ratchet\Wamp\WampServer(
$manager
)
),
$webSock
);
$loop->run();
<?php
namespace Seedstream\Transmission;
use Seedstream\Torrent;
class ActionDispatcher
{
private $execPath;
public function __construct($execPath)
{
$this->execPath = $execPath;
}
public function start(Torrent $torrent)
{
exec(/* ... */);
}
public function stop(Torrent $torrent)
{
exec(/* ... */);
}
public function add(Torrent $torrent)
{
return exec(/* ... */);
}
public function remove(Torrent $torrent)
{
exec(/* ... */);
}
public function getInfo(Torrent $torrent)
{
exec(/* ... */, $info);
return $info;
}
public function getTorrentById($id)
{
exec(/* ... */, $info);
return $info;
}
public function checkUpdates()
{
exec(/* ... */, $info);
return $info;
}
}
<?php
namespace Seedstream\Transmission;
use React\EventLoop\LoopInterface,
Seedstream\Torrent;
class Handler implements TorrentHandler
{
private $dispatcher;
private $factory;
private $torrents = [];
private $onShutdown;
public function __construct(TorrentBuilder $torrentBuilder, ActionDispatcher $dispatcher)
{
$this->torrentBuilder = $torrentBuilder;
$this->dispatcher = $dispatcher;
}
public function addTorrent(Torrent $torrent)
{
$id = $this->dispatcher->add($torrent);
$torrent->setId($id);
$this->torrents[$id] = $torrent;
}
public function removeTorrent(Torrent $torrent)
{
$this->dispatcher->remove($torrent);
unset($this->torrents[$torrent->getId()]);
}
public function getTorrentById($id)
{
if (!isset($this->torrents[$id])) {
if (!$info = $this->dispatcher->getTorrentById($id)) {
throw new TorrentNotFoundException('Y U NO MAEK SENSE?!?!?');
}
$this->torrents[$id] = $this->torrentBuilder->build($info);
}
return $this->torrents[$id];
}
public function onNotification(LoopInterface $loop, callable $callback)
{
$timer = $loop->addPeriodicTimer(4, function() use ($callback) {
if ($eventInfo = $this->dispatcher->checkUpdates()) {
call_user_func($callback, $eventInfo);
}
});
$this->onShutdown = function() use($loop, $timer) {
$loop->cancelTimer($timer);
};
}
public function shutdown()
{
call_user_func($this->onShutdown);
}
}
<?php
namespace Seedstream\Transmission;
use Seedstream\TorrentHandlerFactory;
class HandlerFactory implements TorrentHandlerFactory
{
private $torrentBuilder;
private $dispatcher;
public function __construct(TorrentBuilder $torrentBuilder, ActionDispatcher $dispatcher)
{
$this->torrentBuilder = $torrentBuilder;
$this->dispatcher = $dispatcher;
}
public function create()
{
return new TransmissionHandler($this->torrentBuilder, $this->dispatcher);
}
}
<?php
namespace Seedstream\Transmission;
use Seedstream\TorrentFactory;
class TorrentBuilder
{
private $torrentFactory;
public function __construct(TorrentFactory $torrentFactory)
{
$this->torrentFactory = $torrentFactory;
}
public function build(array $info)
{
$torrent = $this->torrentFactory->create();
$torrent->setId($info['id']);
// etc
return $torrent;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment