glhcp/server/vendor/topthink/think-swoole/src/websocket/Pusher.php

203 lines
4.0 KiB
PHP
Raw Normal View History

2023-08-10 14:59:52 +08:00
<?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);
}
}
}
}