Skip to content

Commit

Permalink
Initial run of broadcasting events.
Browse files Browse the repository at this point in the history
Includes back-end agnostic driver based system for broadcasting events
onto various web socket providers or message systems.
  • Loading branch information
taylorotwell committed Apr 27, 2015
1 parent 819e7a3 commit 860b29b
Show file tree
Hide file tree
Showing 13 changed files with 525 additions and 0 deletions.
1 change: 1 addition & 0 deletions build/illuminate-split-faster.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ split()
}

split auth src/Illuminate/Auth:git@github.com:illuminate/auth.git "master 5.0 4.2"
split broadcasting src/Illuminate/Broadcasting:git@github.com:illuminate/broadcasting.git "master"
split bus src/Illuminate/Bus:git@github.com:illuminate/bus.git "master 5.0"
split cache src/Illuminate/Cache:git@github.com:illuminate/cache.git "master 5.0 4.2"
split config src/Illuminate/Config:git@github.com:illuminate/config.git "master 5.0 4.2"
Expand Down
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"replace": {
"illuminate/auth": "self.version",
"illuminate/bus": "self.version",
"illuminate/broadcasting": "self.version",
"illuminate/cache": "self.version",
"illuminate/config": "self.version",
"illuminate/console": "self.version",
Expand Down
85 changes: 85 additions & 0 deletions src/Illuminate/Broadcasting/BroadcastEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?php namespace Illuminate\Broadcasting;

use Pusher;
use ReflectionClass;
use Illuminate\Contracts\Queue\Job;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Contracts\Broadcasting\Broadcaster;

class BroadcastEvent
{

/**
* The broadcaster implementation.
*
* @var \Illuminate\Contracts\Broadcasting\Broadcaster
*/
protected $broadcaster;

/**
* Create a new job handler instance.
*
* @param \Illuminate\Contracts\Broadcasting\Broadcaster $broadcaster
* @return void
*/
public function __construct(Broadcaster $broadcaster)
{
$this->broadcaster = $broadcaster;
}

/**
* Handle the queued job.
*
* @param \Illuminate\Contracts\Jobs\Job $job
* @param array $data
* @return void
*/
public function fire(Job $job, array $data)
{
$event = unserialize($data['event']);

$this->broadcaster->broadcast(
$event->broadcastOn(), get_class($event), $this->getPayloadFromEvent($event)
);

$job->delete();
}

/**
* Get the payload for the given event.
*
* @param mixed $event
* @return array
*/
protected function getPayloadFromEvent($event)
{
if (method_exists($event, 'broadcastWith')) {
return $event->broadcastWith();
}

$payload = [];

foreach ((new ReflectionClass($event))->getProperties() as $property) {
if ($property->isPublic()) {
$payload[$property->getName()] = $this->formatProperty($property->getValue($event));
}
}

return $payload;
}

/**
* Format the given value for a property.
*
* @param mixed $value
* @return mixed
*/
protected function formatProperty($value)
{
if ($value instanceof Arrayable) {
return $value->toArray();
}

return $value;
}
}
181 changes: 181 additions & 0 deletions src/Illuminate/Broadcasting/BroadcastManager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
<?php namespace Illuminate\Broadcasting;

use Pusher;
use Closure;
use InvalidArgumentException;
use Illuminate\Broadcasting\PusherBroadcaster;
use Illuminate\Contracts\Broadcasting\Factory as FactoryContract;

class BroadcastManager implements FactoryContract
{

/**
* The application instance.
*
* @var \Illuminate\Foundation\Application
*/
protected $app;

/**
* The array of resolved broadcast drivers.
*
* @var array
*/
protected $drivers = [];

/**
* The registered custom driver creators.
*
* @var array
*/
protected $customCreators = [];

/**
* Create a new manager instance.
*
* @param \Illuminate\Foundation\Application $app
* @return void
*/
public function __construct($app)
{
$this->app = $app;
}

/**
* Get a driver instance.
*
* @param string $driver
* @return mixed
*/
public function connection($driver = null)
{
return $this->driver($driver);
}

/**
* Get a driver instance.
*
* @param string $name
* @return mixed
*/
public function driver($name = null)
{
$name = $name ?: $this->getDefaultDriver();

return $this->drivers[$name] = $this->get($name);
}

/**
* Attempt to get the connection from the local cache.
*
* @param string $name
* @return \Illuminate\Contracts\Broadcasting\Broadcaster
*/
protected function get($name)
{
return isset($this->drivers[$name]) ? $this->drivers[$name] : $this->resolve($name);
}

/**
* Resolve the given store.
*
* @param string $name
* @return \Illuminate\Contracts\Broadcasting\Broadcaster
*/
protected function resolve($name)
{
$config = $this->getConfig($name);

if (is_null($config)) {
throw new InvalidArgumentException("Broadcaster [{$name}] is not defined.");
}

if (isset($this->customCreators[$config['driver']])) {
return $this->callCustomCreator($config);
} else {
return $this->{"create".ucfirst($config['driver'])."Driver"}($config);
}
}

/**
* Call a custom driver creator.
*
* @param array $config
* @return mixed
*/
protected function callCustomCreator(array $config)
{
return $this->customCreators[$config['driver']]($this->app, $config);
}

/**
* Create an instance of the driver.
*
* @param array $config
* @return \Illuminate\Contracts\Broadcasting\Broadcaster
*/
protected function createPusherDriver(array $config)
{
return new PusherBroadcaster(
new Pusher($config['key'], $config['secret'], $config['app_id'])
);
}

/**
* Get the connection configuration.
*
* @param string $name
* @return array
*/
protected function getConfig($name)
{
return $this->app['config']["broadcast.connections.{$name}"];
}

/**
* Get the default driver name.
*
* @return string
*/
public function getDefaultDriver()
{
return $this->app['config']['broadcast.default'];
}

/**
* Set the default driver name.
*
* @param string $name
* @return void
*/
public function setDefaultDriver($name)
{
$this->app['config']['broadcast.default'] = $name;
}

/**
* Register a custom driver creator Closure.
*
* @param string $driver
* @param \Closure $callback
* @return $this
*/
public function extend($driver, Closure $callback)
{
$this->customCreators[$driver] = $callback;

return $this;
}

/**
* Dynamically call the default driver instance.
*
* @param string $method
* @param array $parameters
* @return mixed
*/
public function __call($method, $parameters)
{
return call_user_func_array(array($this->driver(), $method), $parameters);
}
}
48 changes: 48 additions & 0 deletions src/Illuminate/Broadcasting/BroadcastServiceProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php namespace Illuminate\Broadcasting;

use Illuminate\Support\ServiceProvider;

class BroadcastServiceProvider extends ServiceProvider
{

/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = true;

/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->app->singleton('Illuminate\Broadcasting\BroadcastManager', function ($app) {
return new BroadcastManager($app);
});

$this->app->singleton('Illuminate\Contracts\Broadcasting\Broadcaster', function ($app) {
return $app->make('Illuminate\Broadcasting\BroadcastManager')->connection();
});

$this->app->alias(
'Illuminate\Broadcasting\BroadcastManager', 'Illuminate\Contracts\Broadcasting\Factory'
);
}

/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return [
'Illuminate\Broadcasting\BroadcastManager',
'Illuminate\Contracts\Broadcasting\Factory',
'Illuminate\Contracts\Broadcasting\Broadcaster',
];
}
}
34 changes: 34 additions & 0 deletions src/Illuminate/Broadcasting/PusherBroadcaster.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php namespace Illuminate\Broadcasting;

use Pusher;
use Illuminate\Contracts\Broadcasting\Broadcaster;

class PusherBroadcaster implements Broadcaster
{

/**
* The Pusher SDK instance.
*
* @var \Pusher
*/
protected $pusher;

/**
* Create a new broadcaster instance.
*
* @param Pusher $pusher
* @return void
*/
public function __construct(Pusher $pusher)
{
$this->pusher = $pusher;
}

/**
* {@inheritdoc}
*/
public function broadcast(array $channels, $event, array $payload = array())
{
$this->pusher->trigger($channels, $event, $payload);
}
}
Loading

0 comments on commit 860b29b

Please sign in to comment.