This commit is contained in:
freek 2018-11-21 22:36:50 +01:00
parent f279261b57
commit 6768eed53f
4 changed files with 52 additions and 6 deletions

View File

@ -18,6 +18,11 @@ class Channel
$this->channelId = $channelId; $this->channelId = $channelId;
} }
public function hasConnections(): bool
{
return count($this->connections) > 0;
}
/** /**
* @link https://pusher.com/docs/pusher_protocol#presence-channel-events * @link https://pusher.com/docs/pusher_protocol#presence-channel-events
* *
@ -35,6 +40,11 @@ class Channel
])); ]));
} }
public function unsubscribe(ConnectionInterface $connection)
{
unset($this->connections[$connection->socketId]);
}
protected function saveConnection(ConnectionInterface $conn) protected function saveConnection(ConnectionInterface $conn)
{ {
$this->connections[$conn->socketId] = $conn; $this->connections[$conn->socketId] = $conn;
@ -49,10 +59,8 @@ class Channel
public function broadcastToOthers($conn, $payload) public function broadcastToOthers($conn, $payload)
{ {
Collection::make($this->connections)->reject(function($connection) use ($conn) { Collection::make($this->connections)->reject(function ($connection) use ($conn) {
return $connection->socketId === $conn->socketId; return $connection->socketId === $conn->socketId;
})->each->send(json_encode($payload)); })->each->send(json_encode($payload));
} }
//TODO: add unsubscribe
} }

View File

@ -3,6 +3,8 @@
namespace BeyondCode\LaravelWebSockets\LaravelEcho\Pusher\Channels; namespace BeyondCode\LaravelWebSockets\LaravelEcho\Pusher\Channels;
use Ratchet\ConnectionInterface;
class ChannelManager class ChannelManager
{ {
/** @var array */ /** @var array */
@ -13,7 +15,7 @@ class ChannelManager
public function findOrCreate(string $appId, string $channelId): Channel public function findOrCreate(string $appId, string $channelId): Channel
{ {
if (! isset($this->channels[$appId][$channelId])) { if (!isset($this->channels[$appId][$channelId])) {
/**TODO: make this variable to go away */ /**TODO: make this variable to go away */
$channelClass = $this->detectChannelClass($channelId); $channelClass = $this->detectChannelClass($channelId);
@ -28,15 +30,30 @@ class ChannelManager
return $this->channels[$appId][$channelId] ?? null; return $this->channels[$appId][$channelId] ?? null;
} }
protected function detectChannelClass($channelId) : string protected function detectChannelClass($channelId): string
{ {
if (starts_with($channelId, 'private-')) { if (starts_with($channelId, 'private-')) {
return PrivateChannel::class; return PrivateChannel::class;
} }
if(starts_with($channelId, 'presence-')) { if (starts_with($channelId, 'presence-')) {
return PresenceChannel::class; return PresenceChannel::class;
} }
return Channel::class; return Channel::class;
} }
public function removeFromAllChannels(ConnectionInterface $connection)
{
collect($this->channels[$connection->appId])->each->unsubscribe($connection);
collect($this->channels[$connection->appId])
->reject->hasConnections()
->each(function (Channel $channel, string $channelId) use ($connection) {
unset($this->channels[$connection->appId][$channelId]);
});
if (count($this->channels[$connection->appId]) === 0) {
unset($this->channels[$connection->appId]);
};
}
} }

View File

@ -31,6 +31,13 @@ class PresenceChannel extends Channel
//TODO: send member_added message back to client, and broadcast to everyone on channel //TODO: send member_added message back to client, and broadcast to everyone on channel
} }
public function unsubscribe(ConnectionInterface $connection)
{
parent::unsubscribe($connection);
//TODO: send member_removed message back to client, and broadcast to everyone on channel
}
/** /**
* @return array * @return array
*/ */

View File

@ -6,6 +6,7 @@ use Ratchet\ConnectionInterface;
use Ratchet\RFC6455\Messaging\MessageInterface; use Ratchet\RFC6455\Messaging\MessageInterface;
use BeyondCode\LaravelWebSockets\WebSocketController; use BeyondCode\LaravelWebSockets\WebSocketController;
use BeyondCode\LaravelWebSockets\LaravelEcho\Pusher\Channels\ChannelManager; use BeyondCode\LaravelWebSockets\LaravelEcho\Pusher\Channels\ChannelManager;
use stdClass;
class EchoServer extends WebSocketController class EchoServer extends WebSocketController
{ {
@ -75,6 +76,11 @@ class EchoServer extends WebSocketController
} }
} }
public function onClose(ConnectionInterface $connection)
{
$this->channelManager->removeFromAllChannels($connection);
}
/** /**
* @link https://pusher.com/docs/pusher_protocol#ping-pong * @link https://pusher.com/docs/pusher_protocol#ping-pong
* @param ConnectionInterface $conn * @param ConnectionInterface $conn
@ -97,6 +103,14 @@ class EchoServer extends WebSocketController
$channel->subscribe($conn, $payload); $channel->subscribe($conn, $payload);
} }
public function pusherUnsubscribe(ConnectionInterface $connection, stdClass $payload)
{
$channel = $this->channelManager->findOrCreate($connection->appId, $payload->channel);
$channel->unsubscribe($connection);
}
protected function buildPayload($event, $data = []) protected function buildPayload($event, $data = [])
{ {
return json_encode([ return json_encode([