| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203 |
- <?php
- namespace think\swoole\websocket;
- use Swoole\Server;
- /**
- * Class Pusher
- */
- class Pusher
- {
- /**
- * @var Server|\Swoole\WebSocket\Server
- */
- protected $server;
- /**
- * @var int
- */
- protected $sender;
- /**
- * @var array
- */
- protected $descriptors;
- /**
- * @var bool
- */
- protected $broadcast;
- /**
- * @var bool
- */
- protected $assigned;
- /**
- * @var string
- */
- protected $payload;
- /**
- * Push constructor.
- *
- * @param Server $server
- * @param int $sender
- * @param array $descriptors
- * @param bool $broadcast
- * @param bool $assigned
- * @param string $payload
- */
- public function __construct(
- Server $server,
- string $payload,
- int $sender = 0,
- array $descriptors = [],
- bool $broadcast = false,
- bool $assigned = false
- )
- {
- $this->sender = $sender;
- $this->descriptors = $descriptors;
- $this->broadcast = $broadcast;
- $this->assigned = $assigned;
- $this->payload = $payload;
- $this->server = $server;
- }
- /**
- * @return int
- */
- public function getSender(): int
- {
- return $this->sender;
- }
- /**
- * @return array
- */
- public function getDescriptors(): array
- {
- return $this->descriptors;
- }
- /**
- * @param int $descriptor
- *
- * @return self
- */
- public function addDescriptor($descriptor): self
- {
- return $this->addDescriptors([$descriptor]);
- }
- /**
- * @param array $descriptors
- *
- * @return self
- */
- public function addDescriptors(array $descriptors): self
- {
- $this->descriptors = array_values(
- array_unique(
- array_merge($this->descriptors, $descriptors)
- )
- );
- return $this;
- }
- /**
- * @param int $descriptor
- *
- * @return bool
- */
- public function hasDescriptor(int $descriptor): bool
- {
- return in_array($descriptor, $this->descriptors);
- }
- /**
- * @return bool
- */
- public function isBroadcast(): bool
- {
- return $this->broadcast;
- }
- /**
- * @return bool
- */
- public function isAssigned(): bool
- {
- return $this->assigned;
- }
- /**
- * @return string
- */
- public function getPayload(): string
- {
- return $this->payload;
- }
- /**
- * @return bool
- */
- public function shouldBroadcast(): bool
- {
- return $this->broadcast && empty($this->descriptors) && !$this->assigned;
- }
- /**
- * Returns all descriptors that are websocket
- *
- * @return array
- */
- protected function getWebsocketConnections(): array
- {
- return array_filter(iterator_to_array($this->server->connections), function ($fd) {
- return (bool) ($this->server->getClientInfo($fd)['websocket_status'] ?? false);
- });
- }
- /**
- * @param int $fd
- *
- * @return bool
- */
- protected function shouldPushToDescriptor(int $fd): bool
- {
- if (!$this->server->isEstablished($fd)) {
- return false;
- }
- return !$this->broadcast || $this->sender !== (int) $fd;
- }
- /**
- * Push message to related descriptors
- * @return void
- */
- public function push(): void
- {
- // attach sender if not broadcast
- if (!$this->broadcast && $this->sender && !$this->hasDescriptor($this->sender)) {
- $this->addDescriptor($this->sender);
- }
- // check if to broadcast to other clients
- if ($this->shouldBroadcast()) {
- $this->addDescriptors($this->getWebsocketConnections());
- }
- // push message to designated fds
- foreach ($this->descriptors as $descriptor) {
- if ($this->shouldPushToDescriptor($descriptor)) {
- $this->server->push($descriptor, $this->payload);
- }
- }
- }
- }
|