BroadcastManager.php 7.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. <?php
  2. namespace Illuminate\Broadcasting;
  3. use Closure;
  4. use Pusher\Pusher;
  5. use Psr\Log\LoggerInterface;
  6. use InvalidArgumentException;
  7. use Illuminate\Broadcasting\Broadcasters\LogBroadcaster;
  8. use Illuminate\Broadcasting\Broadcasters\NullBroadcaster;
  9. use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
  10. use Illuminate\Broadcasting\Broadcasters\RedisBroadcaster;
  11. use Illuminate\Broadcasting\Broadcasters\PusherBroadcaster;
  12. use Illuminate\Contracts\Broadcasting\Factory as FactoryContract;
  13. /**
  14. * @mixin \Illuminate\Contracts\Broadcasting\Broadcaster
  15. */
  16. class BroadcastManager implements FactoryContract
  17. {
  18. /**
  19. * The application instance.
  20. *
  21. * @var \Illuminate\Foundation\Application
  22. */
  23. protected $app;
  24. /**
  25. * The array of resolved broadcast drivers.
  26. *
  27. * @var array
  28. */
  29. protected $drivers = [];
  30. /**
  31. * The registered custom driver creators.
  32. *
  33. * @var array
  34. */
  35. protected $customCreators = [];
  36. /**
  37. * Create a new manager instance.
  38. *
  39. * @param \Illuminate\Foundation\Application $app
  40. * @return void
  41. */
  42. public function __construct($app)
  43. {
  44. $this->app = $app;
  45. }
  46. /**
  47. * Register the routes for handling broadcast authentication and sockets.
  48. *
  49. * @param array|null $attributes
  50. * @return void
  51. */
  52. public function routes(array $attributes = null)
  53. {
  54. if ($this->app->routesAreCached()) {
  55. return;
  56. }
  57. $attributes = $attributes ?: ['middleware' => ['web']];
  58. $this->app['router']->group($attributes, function ($router) {
  59. $router->match(
  60. ['get', 'post'], '/broadcasting/auth',
  61. '\\'.BroadcastController::class.'@authenticate'
  62. );
  63. });
  64. }
  65. /**
  66. * Get the socket ID for the given request.
  67. *
  68. * @param \Illuminate\Http\Request|null $request
  69. * @return string|null
  70. */
  71. public function socket($request = null)
  72. {
  73. if (! $request && ! $this->app->bound('request')) {
  74. return;
  75. }
  76. $request = $request ?: $this->app['request'];
  77. return $request->header('X-Socket-ID');
  78. }
  79. /**
  80. * Begin broadcasting an event.
  81. *
  82. * @param mixed|null $event
  83. * @return \Illuminate\Broadcasting\PendingBroadcast|void
  84. */
  85. public function event($event = null)
  86. {
  87. return new PendingBroadcast($this->app->make('events'), $event);
  88. }
  89. /**
  90. * Queue the given event for broadcast.
  91. *
  92. * @param mixed $event
  93. * @return void
  94. */
  95. public function queue($event)
  96. {
  97. $connection = $event instanceof ShouldBroadcastNow ? 'sync' : null;
  98. if (is_null($connection) && isset($event->connection)) {
  99. $connection = $event->connection;
  100. }
  101. $queue = null;
  102. if (method_exists($event, 'broadcastQueue')) {
  103. $queue = $event->broadcastQueue();
  104. } elseif (isset($event->broadcastQueue)) {
  105. $queue = $event->broadcastQueue;
  106. } elseif (isset($event->queue)) {
  107. $queue = $event->queue;
  108. }
  109. $this->app->make('queue')->connection($connection)->pushOn(
  110. $queue, new BroadcastEvent(clone $event)
  111. );
  112. }
  113. /**
  114. * Get a driver instance.
  115. *
  116. * @param string $driver
  117. * @return mixed
  118. */
  119. public function connection($driver = null)
  120. {
  121. return $this->driver($driver);
  122. }
  123. /**
  124. * Get a driver instance.
  125. *
  126. * @param string|null $name
  127. * @return mixed
  128. */
  129. public function driver($name = null)
  130. {
  131. $name = $name ?: $this->getDefaultDriver();
  132. return $this->drivers[$name] = $this->get($name);
  133. }
  134. /**
  135. * Attempt to get the connection from the local cache.
  136. *
  137. * @param string $name
  138. * @return \Illuminate\Contracts\Broadcasting\Broadcaster
  139. */
  140. protected function get($name)
  141. {
  142. return $this->drivers[$name] ?? $this->resolve($name);
  143. }
  144. /**
  145. * Resolve the given store.
  146. *
  147. * @param string $name
  148. * @return \Illuminate\Contracts\Broadcasting\Broadcaster
  149. *
  150. * @throws \InvalidArgumentException
  151. */
  152. protected function resolve($name)
  153. {
  154. $config = $this->getConfig($name);
  155. if (is_null($config)) {
  156. throw new InvalidArgumentException("Broadcaster [{$name}] is not defined.");
  157. }
  158. if (isset($this->customCreators[$config['driver']])) {
  159. return $this->callCustomCreator($config);
  160. }
  161. $driverMethod = 'create'.ucfirst($config['driver']).'Driver';
  162. if (! method_exists($this, $driverMethod)) {
  163. throw new InvalidArgumentException("Driver [{$config['driver']}] is not supported.");
  164. }
  165. return $this->{$driverMethod}($config);
  166. }
  167. /**
  168. * Call a custom driver creator.
  169. *
  170. * @param array $config
  171. * @return mixed
  172. */
  173. protected function callCustomCreator(array $config)
  174. {
  175. return $this->customCreators[$config['driver']]($this->app, $config);
  176. }
  177. /**
  178. * Create an instance of the driver.
  179. *
  180. * @param array $config
  181. * @return \Illuminate\Contracts\Broadcasting\Broadcaster
  182. */
  183. protected function createPusherDriver(array $config)
  184. {
  185. return new PusherBroadcaster(
  186. new Pusher($config['key'], $config['secret'],
  187. $config['app_id'], $config['options'] ?? [])
  188. );
  189. }
  190. /**
  191. * Create an instance of the driver.
  192. *
  193. * @param array $config
  194. * @return \Illuminate\Contracts\Broadcasting\Broadcaster
  195. */
  196. protected function createRedisDriver(array $config)
  197. {
  198. return new RedisBroadcaster(
  199. $this->app->make('redis'), $config['connection'] ?? null
  200. );
  201. }
  202. /**
  203. * Create an instance of the driver.
  204. *
  205. * @param array $config
  206. * @return \Illuminate\Contracts\Broadcasting\Broadcaster
  207. */
  208. protected function createLogDriver(array $config)
  209. {
  210. return new LogBroadcaster(
  211. $this->app->make(LoggerInterface::class)
  212. );
  213. }
  214. /**
  215. * Create an instance of the driver.
  216. *
  217. * @param array $config
  218. * @return \Illuminate\Contracts\Broadcasting\Broadcaster
  219. */
  220. protected function createNullDriver(array $config)
  221. {
  222. return new NullBroadcaster;
  223. }
  224. /**
  225. * Get the connection configuration.
  226. *
  227. * @param string $name
  228. * @return array
  229. */
  230. protected function getConfig($name)
  231. {
  232. return $this->app['config']["broadcasting.connections.{$name}"];
  233. }
  234. /**
  235. * Get the default driver name.
  236. *
  237. * @return string
  238. */
  239. public function getDefaultDriver()
  240. {
  241. return $this->app['config']['broadcasting.default'];
  242. }
  243. /**
  244. * Set the default driver name.
  245. *
  246. * @param string $name
  247. * @return void
  248. */
  249. public function setDefaultDriver($name)
  250. {
  251. $this->app['config']['broadcasting.default'] = $name;
  252. }
  253. /**
  254. * Register a custom driver creator Closure.
  255. *
  256. * @param string $driver
  257. * @param \Closure $callback
  258. * @return $this
  259. */
  260. public function extend($driver, Closure $callback)
  261. {
  262. $this->customCreators[$driver] = $callback;
  263. return $this;
  264. }
  265. /**
  266. * Dynamically call the default driver instance.
  267. *
  268. * @param string $method
  269. * @param array $parameters
  270. * @return mixed
  271. */
  272. public function __call($method, $parameters)
  273. {
  274. return $this->driver()->$method(...$parameters);
  275. }
  276. }