Skip to content

Commit

Permalink
Merge pull request #10 from MatviiB/develop
Browse files Browse the repository at this point in the history
Upgrade. add users direct messages
  • Loading branch information
MatviiB authored May 12, 2018
2 parents d240cec + 8b7e17d commit 8d057db
Show file tree
Hide file tree
Showing 10 changed files with 200 additions and 88 deletions.
5 changes: 3 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"socketstream"
],
"type": "library",
"version": "v1.1.0",
"version": "v1.2.0",
"license": "MIT",
"authors": [
{
Expand All @@ -36,7 +36,8 @@
"autoload": {
"psr-4": {
"MatviiB\\Notifier\\": "src/"
}
},
"files": ["src/helper_connector.php"]
},
"extra": {
"laravel": {
Expand Down
33 changes: 17 additions & 16 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,22 @@
</p>

### Usage Example
#### For example send new values to chart on some page synchronously to each user.
#### Send new values to chart on some page synchronously to each user:
#### `event(new Notify($data, ['chart']));`
#### Or to users with `id` 3 and 5: `event(new Notify($data, ['chart'], [3, 5]));`
![laravel socket server](https://gitlab.com/MatviiB/assets/raw/master/ezgif.com-video-to-gif.gif)

### Base concepts
This package sends data ONLY to named routes declared as `GET`.

To view available routes you can run `php artisan notifier:init show` command. It will display available routes in the table and initiate the socket server.

`event(new Notify($data));` - send to all routes.

`event(new Notify($data, $routes));` - send to routes in `$routes` array.

`event(new Notify($data, $routes, $users));` - send to routes in `$routes` and only to users in `$users`.

### Installation

```
Expand Down Expand Up @@ -51,17 +64,11 @@ Also you can run `php artisan notifier:init show` - this command will show you l

### Usage

At first you need to add `@include('notifier::connect')` before than you will use `socket.addEventListener()` to your view or main layout to use on the ALL pages.

Anywhere in your application add next event to send data to array of NAMED ROUTES. Example:
At first you need to add `@include('notifier::connect')` before you'll use `socket.addEventListener()` to your view or main layout to use it with ALL pages.

`event(new Notify($data, ['chart', 'index']));`
Anywhere in your application add next event:

Event WITHOUT array of routes will send data to EACH page which are listen the sockets. Example:

`event(new Notify($data));`

Event with urls instead of named routes WILL NOT WORK.
`event(new Notify($data, ['some-route-name']));`

On front-end part add event listener
```
Expand Down Expand Up @@ -147,9 +154,3 @@ Run: `php artisan notifier:init`
Run in another shell: `php artisan test`

Open `/chart` page.

## Will develop next

Add abillity to send messages to special user.

`event(new Notify($data, $routes, $users));`
170 changes: 123 additions & 47 deletions src/Commands/Notifier.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace MatviiB\Notifier\Commands;

use Cache;
use Closure;
use Illuminate\Routing\Router;
use Illuminate\Console\Command;
Expand Down Expand Up @@ -49,7 +50,28 @@ class Notifier extends Command
*
* @var array
*/
protected $headers = ['Method', 'Name', 'Middleware'];
private $headers = ['Method', 'Name', 'Middleware'];

/**
* Socket connections.
*
* @var array
*/
private $connects;

/**
* Connections to pages.
*
* @array
*/
private $per_pages;

/**
* Connections to users.
*
* @array
*/
private $per_users;

/**
* Create a new command instance.
Expand All @@ -62,7 +84,9 @@ public function __construct(Router $router)

$this->server = new SocketServer();
$this->router = $router;
$this->routes = $router->getRoutes();
$this->routes = $this->getRoutes();

$this->connects = $this->per_pages = $this->per_users = [];
}

/**
Expand All @@ -72,19 +96,14 @@ public function __construct(Router $router)
*/
public function handle()
{
$routes = $this->getRoutes();

if ($this->argument('show')) {
$this->displayRoutes($routes);
$this->displayRoutes();
}

$socket = $this->server->init();

$connects = [];
$per_pages = [];

while (true) {
$read = $connects;
$read = $this->connects;
$read[] = $socket;
$write = $except = [];

Expand All @@ -94,25 +113,8 @@ public function handle()

if (in_array($socket, $read) && ($connection = stream_socket_accept($socket, -1))) {

$info = $this->server->handshake($connection);

if ($info) {
if (isset($info['Socket-pass']) && $info['Socket-pass'] === config('notifier.socket_pass')) {
foreach ($connects as $key => $c) {
if (isset($per_pages[$key])) {
if (isset($info['Routes'])) {
if (in_array($per_pages[$key], json_decode($info['Routes']))) {
fwrite($c, $this->server->encode($info['Payload']));
}
} elseif (!isset($info['Route'])) {
fwrite($c, $this->server->encode($info['Payload']));
}
}
}
} else {
$connects[] = $connection;
// $this->server->onOpen($connection, $info);
}
if ($info = $this->server->handshake($connection)) {
$this->computeIncomingInfo($info, $connection);
}

unset($read[array_search($socket, $read)]);
Expand All @@ -123,42 +125,117 @@ public function handle()
$data = fread($connection, 100000);

if (!$data) {
fclose($connection);
$connection_key = array_search($connection, $connects);
unset($connects[$connection_key]);
unset($per_pages[$connection_key]);
$this->close($connection);
continue;
}

$route = $this->server->decode($data)['payload'];
$connection_request = explode(':', $this->server->decode($data)['payload']);
$route = $connection_request[0];

if (in_array($route, array_column($routes, 'name'))) {
$connection_key = array_search($connection, $connects);
$per_pages[$connection_key] = $route;
if (isset($connection_request[1])) {
$unique_id = $connection_request[1];
}

if (in_array($route, array_column($this->routes, 'name'))) {
$connection_key = array_search($connection, $this->connects);
$this->per_pages[$connection_key] = $route;

if (isset($unique_id) && Cache::has('notifier:' . $unique_id)) {
$this->per_users[$connection_key] = Cache::get('notifier:' . $unique_id);
}
} else {
fclose($connection);
$connection_key = array_search($connection, $connects);
unset($connects[$connection_key]);
unset($per_pages[$connection_key]);
$this->close($connection);
continue;
}
// $this->server->onMessage($connect, $data);

unset($route, $unique_id, $connection_request);
//$this->server->onMessage($connect, $data);
}
}

fclose($socket);
}

/**
* @param $info
* @param $connection
*/
private function computeIncomingInfo($info, $connection)
{
if (isset($info['Socket-pass']) && $info['Socket-pass'] === config('notifier.socket_pass')) {
$this->computeSystemMessage($info);
} else {
$this->connects[] =$connection;
//$this->server->onOpen($connection, $info);
}
}

/**
* @param $info
*/
private function computeSystemMessage($info)
{
foreach ($this->connects as $key => $connection) {
if (isset($this->per_pages[$key])) {
if (isset($info['Routes'])) {
$this->sendToRoutes($key, $connection, $info);
} elseif (!isset($info['Route'])) {
fwrite($connection, $this->server->encode($info['Payload']));
}
}
}
}

/**
* @param $key
* @param $connection
* @param $info
*/
private function sendToRoutes($key, $connection, $info)
{
if (in_array($this->per_pages[$key], json_decode($info['Routes']))) {
if (isset($info['Users'])) {
$this->sendToUsers($key, $connection, $info);
} else {
fwrite($connection, $this->server->encode($info['Payload']));
}
}
}

/**
* @param $key
* @param $connection
* @param $info
*/
private function sendToUsers($key, $connection, $info)
{
if (isset($this->per_users[$key]) && in_array($this->per_users[$key], json_decode($info['Users']))) {
fwrite($connection, $this->server->encode($info['Payload']));
}
}

/**
* @param $connection
*/
private function close($connection)
{
fclose($connection);
$connection_key = array_search($connection, $this->connects);
unset($this->connects[$connection_key]);
unset($this->per_pages[$connection_key]);
unset($this->per_users[$connection_key]);
}

/**
* Compile the routes into a displayable format.
*
* @return array
*/
protected function getRoutes()
private function getRoutes()
{
$result = [];

foreach ($this->routes as $route) {
foreach ($this->router->getRoutes() as $route) {

$methods = $route->methods();
if (!in_array('GET', $methods)) {
Expand Down Expand Up @@ -188,12 +265,11 @@ protected function getRoutes()
/**
* Display the route information on the console.
*
* @param array $routes
* @return void
*/
protected function displayRoutes(array $routes)
private function displayRoutes()
{
$this->table($this->headers, $routes);
$this->table($this->headers, $this->routes);
}

/**
Expand All @@ -202,7 +278,7 @@ protected function displayRoutes(array $routes)
* @param \Illuminate\Routing\Route $route
* @return array
*/
protected function getMiddleware($route)
private function getMiddleware($route)
{
return collect($route->gatherMiddleware())->map(function ($middleware) {
return $middleware instanceof Closure ? 'Closure' : $middleware;
Expand Down
15 changes: 11 additions & 4 deletions src/Events/Notify.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,25 @@ class Notify
/**
* @var
*/
public $route;
public $routes;

/**
* @var
*/
public $users;

/**
* Create a new event instance.
*
* @param $data
* @param $route
* @param $routes
* @param $users
*/
public function __construct($data, $route = false)
public function __construct($data, $routes = false, $users = false)
{
$this->data = $data;
$this->route = $route;
$this->routes = $routes;
$this->users = $users;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/Listeners/NotifyListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,6 @@ public function __construct()
*/
public function handle(Notify $event)
{
with(new SystemMessage())->send($event->data, $event->route);
with(new SystemMessage())->send($event->data, $event->routes, $event->users);
}
}
4 changes: 3 additions & 1 deletion src/NotifierServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ public function boot()
*/
public function register()
{
require_once('helper_connector.php');

$events = $this->app->make(Dispatcher::class);

foreach ($this->events as $event => $listeners) {
Expand All @@ -38,7 +40,7 @@ public function register()
}
}

$this->loadViewsFrom(__DIR__.'/views', 'notifier');
$this->loadViewsFrom(__DIR__ . '/views', 'notifier');

if ($this->app->runningInConsole()) {

Expand Down
4 changes: 4 additions & 0 deletions src/SocketServer.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ public function getMessage($data, $routes = false, $users = false)
$request .= "\r\n" . "Routes: " . json_encode($routes);
}

if (isset($users) && is_array($users) && count($users)) {
$request .= "\r\n" . "Users: " . json_encode($users);
}

return $request;
}

Expand Down
Loading

0 comments on commit 8d057db

Please sign in to comment.