This commit is contained in:
Marcel Pociot 2018-11-22 22:02:36 +01:00
parent 6b7233ef0a
commit 54e2287646
4 changed files with 37 additions and 24 deletions

View File

@ -53,7 +53,11 @@ abstract class EchoController implements HttpServerInterface
{ {
if ($exception instanceof HttpException) if ($exception instanceof HttpException)
{ {
$response = new Response($exception->getStatusCode(), $exception->getHeaders(), $exception->getMessage()); $response = new Response($exception->getStatusCode(), [
'Content-Type' => 'application/json'
], json_encode([
'error' => $exception->getMessage()
]));
$connection->send(gPsr\str($response)); $connection->send(gPsr\str($response));
$connection->close(); $connection->close();

View File

@ -19,18 +19,12 @@ class FetchChannel extends EchoController
public function __invoke(Request $request) public function __invoke(Request $request)
{ {
$this->verifySignature($request); $channel = $this->channelManager->find($request->appId, $request->channelName);
foreach ($request->json()->get('channels', []) as $channelId) { if (is_null($channel)) {
$channel = $this->channelManager->find($request->appId, $channelId); throw new HttpException(404, 'Unknown channel "'.$request->channelName.'"');
optional($channel)->broadcast([
'channel' => $channelId,
'event' => $request->json()->get('name'),
'data' => $request->json()->get('data'),
]);
} }
return $request->json()->all(); return $channel->toArray();
} }
} }

View File

@ -13,7 +13,7 @@ class Channel
protected $channelId; protected $channelId;
/** @var \Ratchet\ConnectionInterface[] */ /** @var \Ratchet\ConnectionInterface[] */
protected $connections = []; protected $subscriptions = [];
public function __construct(string $channelId) public function __construct(string $channelId)
{ {
@ -22,7 +22,7 @@ class Channel
public function hasConnections(): bool public function hasConnections(): bool
{ {
return count($this->connections) > 0; return count($this->subscriptions) > 0;
} }
protected function verifySignature(ConnectionInterface $connection, stdClass $payload) protected function verifySignature(ConnectionInterface $connection, stdClass $payload)
@ -56,25 +56,33 @@ class Channel
public function unsubscribe(ConnectionInterface $connection) public function unsubscribe(ConnectionInterface $connection)
{ {
unset($this->connections[$connection->socketId]); unset($this->subscriptions[$connection->socketId]);
} }
protected function saveConnection(ConnectionInterface $connection) protected function saveConnection(ConnectionInterface $connection)
{ {
$this->connections[$connection->socketId] = $connection; $this->subscriptions[$connection->socketId] = $connection;
} }
public function broadcast($payload) public function broadcast($payload)
{ {
foreach ($this->connections as $connection) { foreach ($this->subscriptions as $connection) {
$connection->send(json_encode($payload)); $connection->send(json_encode($payload));
} }
} }
public function broadcastToOthers(ConnectionInterface $connection, $payload) public function broadcastToOthers(ConnectionInterface $connection, $payload)
{ {
Collection::make($this->connections)->reject(function ($existingConnection) use ($connection) { Collection::make($this->subscriptions)->reject(function ($existingConnection) use ($connection) {
return $existingConnection->socketId === $connection->socketId; return $existingConnection->socketId === $connection->socketId;
})->each->send(json_encode($payload)); })->each->send(json_encode($payload));
} }
public function toArray(): array
{
return [
'occupied' => count($this->subscriptions) > 0,
'subscription_count' => count($this->subscriptions)
];
}
} }

View File

@ -6,7 +6,7 @@ use Ratchet\ConnectionInterface;
class PresenceChannel extends Channel class PresenceChannel extends Channel
{ {
protected $subscriptions = []; protected $users = [];
/* /*
* @link https://pusher.com/docs/pusher_protocol#presence-channel-events * @link https://pusher.com/docs/pusher_protocol#presence-channel-events
@ -18,7 +18,7 @@ class PresenceChannel extends Channel
$this->saveConnection($connection); $this->saveConnection($connection);
$channelData = json_decode($payload->channel_data); $channelData = json_decode($payload->channel_data);
$this->subscriptions[$connection->socketId] = $channelData; $this->users[$connection->socketId] = $channelData;
// Send the success event // Send the success event
$connection->send(json_encode([ $connection->send(json_encode([
@ -42,21 +42,28 @@ class PresenceChannel extends Channel
'event' => 'pusher_internal:member_removed', 'event' => 'pusher_internal:member_removed',
'channel' => $this->channelId, 'channel' => $this->channelId,
'data' => json_encode([ 'data' => json_encode([
'user_id' => $this->subscriptions[$connection->socketId]->user_id 'user_id' => $this->users[$connection->socketId]->user_id
]) ])
]); ]);
unset($this->subscriptions[$connection->socketId]); unset($this->users[$connection->socketId]);
} }
protected function getChannelData(): array protected function getChannelData(): array
{ {
return [ return [
'presence' => [ 'presence' => [
'ids' => array_map(function($channelData) { return $channelData->user_id; }, $this->subscriptions), 'ids' => array_map(function($channelData) { return $channelData->user_id; }, $this->users),
'hash' => array_map(function($channelData) { return $channelData->user_info; }, $this->subscriptions), 'hash' => array_map(function($channelData) { return $channelData->user_info; }, $this->users),
'count' => count($this->subscriptions) 'count' => count($this->users)
] ]
]; ];
} }
public function toArray(): array
{
return array_merge(parent::toArray(),[
'user_count' => count($this->users),
]);
}
} }