laravel-websockets/src/LaravelEcho/WebSocket/EchoServer.php

121 lines
3.6 KiB
PHP
Raw Normal View History

2018-11-21 11:13:40 +00:00
<?php
namespace BeyondCode\LaravelWebSockets\LaravelEcho\WebSocket;
use Ratchet\ConnectionInterface;
use Ratchet\RFC6455\Messaging\MessageInterface;
use BeyondCode\LaravelWebSockets\WebSocketController;
use BeyondCode\LaravelWebSockets\LaravelEcho\Pusher\Channels\ChannelManager;
2018-11-21 21:36:50 +00:00
use stdClass;
2018-11-21 11:13:40 +00:00
class EchoServer extends WebSocketController
{
/** @var ChannelManager */
protected $channelManager;
public function __construct(ChannelManager $channelManager)
{
$this->channelManager = $channelManager;
}
/**
* When a new connection is opened it will be passed to this method
* @param ConnectionInterface $conn The socket/connection that just connected to your application
* @throws \Exception
*/
function onOpen(ConnectionInterface $conn)
{
2018-11-21 21:11:44 +00:00
2018-11-21 11:13:40 +00:00
dump("Client connected");
2018-11-21 14:42:04 +00:00
/**
* There are a couple things we need to do here:
* 1. Authenticate the incoming request by validating the provided APP-ID is known to us (JSON file lookup?)
*/
2018-11-21 11:13:40 +00:00
$socketId = sprintf("%d.%d", getmypid(), random_int(1, 100000000));
// Store the socketId along with the connection so we can retrieve it.
$conn->socketId = $socketId;
2018-11-21 21:11:44 +00:00
/** @var \GuzzleHttp\Psr7\Request $request */
$request = $conn->httpRequest;
$queryParameters = [];
parse_str($request->getUri()->getQuery(), $queryParameters);
$conn->appId = $queryParameters['appId'];
2018-11-21 11:13:40 +00:00
$conn->send($this->buildPayload('pusher:connection_established', [
'socket_id' => $socketId,
'activity_timeout' => 60,
]));
}
public function onMessage(ConnectionInterface $conn, MessageInterface $msg)
{
$payload = json_decode($msg->getPayload());
dump("Received payload", $payload);
2018-11-21 14:42:04 +00:00
/**
* Pusher events get a special treatment
*/
if (starts_with($payload->event, 'pusher:')) {
$event = camel_case(str_replace(':', '_', $payload->event));
2018-11-21 11:13:40 +00:00
2018-11-21 14:42:04 +00:00
if (method_exists($this, $event)) {
call_user_func([$this, $event], $conn, $payload->data);
}
} else {
// Try to find a channel and broadcast the message to the clients.
2018-11-21 21:11:44 +00:00
$channel = $this->channelManager->find($conn->appId, $payload->channel);
2018-11-21 14:42:04 +00:00
if ($channel) {
$channel->broadcast($payload);
}
2018-11-21 11:13:40 +00:00
}
}
2018-11-21 21:36:50 +00:00
public function onClose(ConnectionInterface $connection)
{
$this->channelManager->removeFromAllChannels($connection);
}
2018-11-21 11:13:40 +00:00
/**
* @link https://pusher.com/docs/pusher_protocol#ping-pong
* @param ConnectionInterface $conn
* @param $payload
*/
protected function pusherPing(ConnectionInterface $conn, $payload)
{
$conn->send($this->buildPayload('pusher:pong'));
}
/**
* @link https://pusher.com/docs/pusher_protocol#pusher-subscribe
* @param ConnectionInterface $conn
* @param $payload
*/
protected function pusherSubscribe(ConnectionInterface $conn, $payload)
{
2018-11-21 21:11:44 +00:00
$channel = $this->channelManager->findOrCreate($conn->appId, $payload->channel);
2018-11-21 11:13:40 +00:00
$channel->subscribe($conn, $payload);
}
2018-11-21 21:36:50 +00:00
public function pusherUnsubscribe(ConnectionInterface $connection, stdClass $payload)
{
$channel = $this->channelManager->findOrCreate($connection->appId, $payload->channel);
$channel->unsubscribe($connection);
}
2018-11-21 11:13:40 +00:00
protected function buildPayload($event, $data = [])
{
return json_encode([
'event' => $event,
'data' => json_encode($data)
]);
}
}