wip
This commit is contained in:
parent
a12c3ba8d0
commit
e94e70b734
|
|
@ -27,7 +27,8 @@
|
|||
"illuminate/console": "5.6.*|5.7.*",
|
||||
"illuminate/http": "5.6.*|5.7.*",
|
||||
"illuminate/routing": "5.6.*|5.7.*",
|
||||
"illuminate/support": "5.6.*|5.7.*"
|
||||
"illuminate/support": "5.6.*|5.7.*",
|
||||
"symfony/psr-http-message-bridge": "^1.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"larapack/dd": "^1.0",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace BeyondCode\LaravelWebsockets\Console;
|
||||
namespace BeyondCode\LaravelWebSockets\Console;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use BeyondCode\LaravelWebSockets\Server\WebSocketServer;
|
||||
|
|
|
|||
|
|
@ -1,11 +1,14 @@
|
|||
<?php
|
||||
|
||||
namespace BeyondCode\LaravelWebsockets\LaravelEcho\Http\Controllers;
|
||||
namespace BeyondCode\LaravelWebSockets\LaravelEcho\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Ratchet\ConnectionInterface;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use GuzzleHttp\Psr7\ServerRequest;
|
||||
use Ratchet\Http\HttpServerInterface;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
use Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory;
|
||||
|
||||
abstract class EchoController implements HttpServerInterface
|
||||
{
|
||||
|
|
@ -39,7 +42,18 @@ abstract class EchoController implements HttpServerInterface
|
|||
*/
|
||||
public function onOpen(ConnectionInterface $conn, RequestInterface $request = null)
|
||||
{
|
||||
$response = $this($request);
|
||||
$queryParameters = [];
|
||||
parse_str($request->getUri()->getQuery(), $queryParameters);
|
||||
|
||||
$serverRequest = (new ServerRequest(
|
||||
$request->getMethod(),
|
||||
$request->getUri(),
|
||||
$request->getHeaders(),
|
||||
$request->getBody(),
|
||||
$request->getProtocolVersion()
|
||||
))->withQueryParams($queryParameters);
|
||||
|
||||
$response = $this(Request::createFromBase((new HttpFoundationFactory)->createRequest($serverRequest)));
|
||||
|
||||
$conn->send(JsonResponse::create($response)->send());
|
||||
$conn->close();
|
||||
|
|
@ -56,5 +70,5 @@ abstract class EchoController implements HttpServerInterface
|
|||
//
|
||||
}
|
||||
|
||||
abstract public function __invoke($request);
|
||||
abstract public function __invoke(Request $request);
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
namespace BeyondCode\LaravelWebSockets\LaravelEcho\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class EventController extends EchoController
|
||||
{
|
||||
|
||||
public function __invoke(Request $request)
|
||||
{
|
||||
return $request->json()->all();
|
||||
}
|
||||
}
|
||||
|
|
@ -2,10 +2,12 @@
|
|||
|
||||
namespace BeyondCode\LaravelWebSockets\LaravelEcho\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class StatusController extends EchoController
|
||||
{
|
||||
|
||||
public function __invoke($request)
|
||||
public function __invoke(Request $request)
|
||||
{
|
||||
return [
|
||||
'subscription_count' => 10
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
namespace BeyondCode\LaravelWebSockets\LaravelEcho\Pusher\Channels;
|
||||
|
||||
use Ratchet\ConnectionInterface;
|
||||
|
||||
class Channel
|
||||
{
|
||||
protected $channelId;
|
||||
|
||||
|
||||
public function __construct($channelId)
|
||||
{
|
||||
$this->channelId = $channelId;
|
||||
}
|
||||
|
||||
public function subscribe(ConnectionInterface $conn, $payload)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
namespace BeyondCode\LaravelWebSockets\LaravelEcho\Pusher\Channels;
|
||||
|
||||
|
||||
class ChannelManager
|
||||
{
|
||||
protected $channels = [];
|
||||
|
||||
public function findOrCreate(string $channelId)
|
||||
{
|
||||
if (! isset($this->channels[$channelId])) {
|
||||
$channelClass = $this->detectChannelClass($channelId);
|
||||
$this->channels[$channelId] = new $channelClass($channelId);
|
||||
}
|
||||
|
||||
return $this->channels[$channelId];
|
||||
}
|
||||
|
||||
protected function detectChannelClass($channelId) : string
|
||||
{
|
||||
if (starts_with($channelId, 'private-')) {
|
||||
return PrivateChannel::class;
|
||||
} elseif(starts_with($channelId, 'presence-')) {
|
||||
return PresenceChannel::class;
|
||||
}
|
||||
return Channel::class;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
namespace BeyondCode\LaravelWebSockets\LaravelEcho\Pusher\Channels;
|
||||
|
||||
use Ratchet\ConnectionInterface;
|
||||
|
||||
class PresenceChannel extends Channel
|
||||
{
|
||||
protected $subscriptions = [];
|
||||
|
||||
public function subscribe(ConnectionInterface $conn, $payload)
|
||||
{
|
||||
$channelData = json_decode($payload->channel_data);
|
||||
$this->subscriptions[$channelData->user_id] = $channelData;
|
||||
|
||||
// Send the success event
|
||||
$conn->send(json_encode([
|
||||
'event' => 'pusher_internal:subscription_succeeded',
|
||||
'channel' => $this->channelId,
|
||||
'data' => json_encode($this->getChannelData())
|
||||
]));
|
||||
}
|
||||
|
||||
protected function getChannelData()
|
||||
{
|
||||
return [
|
||||
'presence' => [
|
||||
'ids' => array_keys($this->subscriptions),
|
||||
'hash' => array_map(function($channelData) { return $channelData->user_info; }, $this->subscriptions),
|
||||
'count' => count($this->subscriptions)
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<?php
|
||||
|
||||
namespace BeyondCode\LaravelWebSockets\LaravelEcho\Pusher\Channels;
|
||||
|
||||
class PrivateChannel extends Channel
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
<?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;
|
||||
|
||||
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)
|
||||
{
|
||||
dump("Client connected");
|
||||
|
||||
$socketId = sprintf("%d.%d", getmypid(), random_int(1, 100000000));
|
||||
|
||||
// Store the socketId along with the connection so we can retrieve it.
|
||||
$conn->socketId = $socketId;
|
||||
|
||||
$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);
|
||||
|
||||
// todo: validate payload
|
||||
$event = camel_case(str_replace(':', '_', $payload->event));
|
||||
|
||||
if (method_exists($this, $event)) {
|
||||
call_user_func([$this, $event], $conn, $payload->data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
$channel = $this->channelManager->findOrCreate($payload->channel);
|
||||
$channel->subscribe($conn, $payload);
|
||||
}
|
||||
|
||||
protected function buildPayload($event, $data = [])
|
||||
{
|
||||
return json_encode([
|
||||
'event' => $event,
|
||||
'data' => json_encode($data)
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
namespace BeyondCode\LaravelWebSockets;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use BeyondCode\LaravelWebSockets\LaravelEcho\Pusher\Channels\ChannelManager;
|
||||
|
||||
class LaravelWebSocketsServiceProvider extends ServiceProvider
|
||||
{
|
||||
|
|
@ -24,5 +25,8 @@ class LaravelWebSocketsServiceProvider extends ServiceProvider
|
|||
$this->app->singleton('websockets.router', function() {
|
||||
return new Router();
|
||||
});
|
||||
$this->app->singleton(ChannelManager::class, function() {
|
||||
return new ChannelManager();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ use Ratchet\WebSocket\WsServer;
|
|||
use Symfony\Component\Routing\Route;
|
||||
use Ratchet\Http\HttpServerInterface;
|
||||
use Symfony\Component\Routing\RouteCollection;
|
||||
use Ratchet\WebSocket\MessageComponentInterface;
|
||||
use BeyondCode\LaravelWebSockets\Exceptions\InvalidWebSocketController;
|
||||
|
||||
class Router
|
||||
|
|
@ -73,11 +74,12 @@ class Router
|
|||
*/
|
||||
public function echo()
|
||||
{
|
||||
//$this->get('/', EchoWebsocketServer::class);
|
||||
$this->get('/app/{appId}', LaravelEcho\WebSocket\EchoServer::class);
|
||||
$this->get('/apps/{appId}/status', LaravelEcho\Http\Controllers\StatusController::class);
|
||||
$this->get('/apps/{appId}/channels', LaravelEcho\Http\Controllers\StatusController::class);
|
||||
$this->get('/apps/{appId}/channels/{channelName}', LaravelEcho\Http\Controllers\StatusController::class);
|
||||
$this->get('/apps/{appId}/channels/{channelName}/users', LaravelEcho\Http\Controllers\StatusController::class);
|
||||
$this->post('/apps/{appId}/events', LaravelEcho\Http\Controllers\EventController::class);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace BeyondCode\LaravelWebsockets\Server;
|
||||
namespace BeyondCode\LaravelWebSockets\Server;
|
||||
|
||||
use Ratchet\Http\Router;
|
||||
use Ratchet\Http\HttpServer;
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ class WebSocketController implements MessageComponentInterface
|
|||
*/
|
||||
function onOpen(ConnectionInterface $conn)
|
||||
{
|
||||
//
|
||||
dump("Client connected");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in New Issue