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)
{
$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->close();

View File

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

View File

@ -13,7 +13,7 @@ class Channel
protected $channelId;
/** @var \Ratchet\ConnectionInterface[] */
protected $connections = [];
protected $subscriptions = [];
public function __construct(string $channelId)
{
@ -22,7 +22,7 @@ class Channel
public function hasConnections(): bool
{
return count($this->connections) > 0;
return count($this->subscriptions) > 0;
}
protected function verifySignature(ConnectionInterface $connection, stdClass $payload)
@ -56,25 +56,33 @@ class Channel
public function unsubscribe(ConnectionInterface $connection)
{
unset($this->connections[$connection->socketId]);
unset($this->subscriptions[$connection->socketId]);
}
protected function saveConnection(ConnectionInterface $connection)
{
$this->connections[$connection->socketId] = $connection;
$this->subscriptions[$connection->socketId] = $connection;
}
public function broadcast($payload)
{
foreach ($this->connections as $connection) {
foreach ($this->subscriptions as $connection) {
$connection->send(json_encode($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;
})->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
{
protected $subscriptions = [];
protected $users = [];
/*
* @link https://pusher.com/docs/pusher_protocol#presence-channel-events
@ -18,7 +18,7 @@ class PresenceChannel extends Channel
$this->saveConnection($connection);
$channelData = json_decode($payload->channel_data);
$this->subscriptions[$connection->socketId] = $channelData;
$this->users[$connection->socketId] = $channelData;
// Send the success event
$connection->send(json_encode([
@ -42,21 +42,28 @@ class PresenceChannel extends Channel
'event' => 'pusher_internal:member_removed',
'channel' => $this->channelId,
'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
{
return [
'presence' => [
'ids' => array_map(function($channelData) { return $channelData->user_id; }, $this->subscriptions),
'hash' => array_map(function($channelData) { return $channelData->user_info; }, $this->subscriptions),
'count' => count($this->subscriptions)
'ids' => array_map(function($channelData) { return $channelData->user_id; }, $this->users),
'hash' => array_map(function($channelData) { return $channelData->user_info; }, $this->users),
'count' => count($this->users)
]
];
}
public function toArray(): array
{
return array_merge(parent::toArray(),[
'user_count' => count($this->users),
]);
}
}