TEST RATCHET

This commit is contained in:
barwie2@st.amu.edu.pl 2020-03-08 20:23:02 +01:00
parent 0a4e3d0fd9
commit 35f0f8135f
4 changed files with 768 additions and 1 deletions

View File

@ -0,0 +1,67 @@
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
use App\Http\Controllers\WebSocketController;
use React\EventLoop\Factory;
use React\Socket\SecureServer;
use React\Socket\Server;
class WebSocketServer extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'websocket:init';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Initializing Websocket server to receive and manage connections';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return void
*/
public function handle()
{
$loop = Factory::create();
$webSock = new SecureServer(
new Server('0.0.0.0:8090', $loop),
$loop,
array(
'local_cert' => '/etc/letsencrypt/live/atcheck.projektstudencki.pl/cert.pem', // path to your cert
'local_pk' => '/etc/letsencrypt/live/atcheck.projektstudencki.pl/privkey.pem', // path to your server private key
'allow_self_signed' => FALSE, // Allow self signed certs (should be false in production)
'verify_peer' => FALSE
)
);
$server = IoServer::factory(
new HttpServer(
new WsServer(
new WebSocketController()
)
),
$webSock
);
$server->run();
}
}

View File

@ -0,0 +1,76 @@
<?php
namespace App\Http\Controllers;
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
class WebSocketController extends Controller implements MessageComponentInterface{
private $connections = [];
/**
* 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){
$this->connections[$conn->resourceId] = compact('conn') + ['user_id' => null];
}
/**
* This is called before or after a socket is closed (depends on how it's closed). SendMessage to $conn will not result in an error if it has already been closed.
* @param ConnectionInterface $conn The socket/connection that is closing/closed
* @throws \Exception
*/
function onClose(ConnectionInterface $conn) {
$disconnectedId = $conn->resourceId;
unset($this->connections[$disconnectedId]);
foreach($this->connections as &$connection)
$connection['conn']->send(json_encode([
'offline_user' => $disconnectedId,
'from_user_id' => 'server control',
'from_resource_id' => null
]));
}
/**
* If there is an error with one of the sockets, or somewhere in the application where an Exception is thrown,
* the Exception is sent back down the stack, handled by the Server and bubbled back up the application through this method
* @param ConnectionInterface $conn
* @param \Exception $e
* @throws \Exception
*/
function onError(ConnectionInterface $conn, \Exception $e){
$userId = $this->connections[$conn->resourceId]['user_id'];
echo "An error has occurred with user $userId: {$e->getMessage()}\n";
unset($this->connections[$conn->resourceId]);
$conn->close();
}
/**
* Triggered when a client sends data through the socket
* @param \Ratchet\ConnectionInterface $conn The socket/connection that sent the message to your application
* @param string $msg The message received
* @throws \Exception
*/
function onMessage(ConnectionInterface $conn, $msg){
if(is_null($this->connections[$conn->resourceId]['user_id'])){
$this->connections[$conn->resourceId]['user_id'] = $msg;
$onlineUsers = [];
foreach($this->connections as $resourceId => &$connection){
$connection['conn']->send(json_encode([$conn->resourceId => $msg]));
if($conn->resourceId != $resourceId)
$onlineUsers[$resourceId] = $connection['user_id'];
}
$conn->send(json_encode(['online_users' => $onlineUsers]));
} else{
$fromUserId = $this->connections[$conn->resourceId]['user_id'];
$msg = json_decode($msg, true);
$this->connections[$msg['to']]['conn']->send(json_encode([
'msg' => $msg['content'],
'from_user_id' => $fromUserId,
'from_resource_id' => $conn->resourceId
]));
}
}
}

View File

@ -9,6 +9,7 @@
"license": "MIT",
"require": {
"php": "^7.2",
"cboden/ratchet": "^0.4.2",
"fideloper/proxy": "^4.0",
"laravel/framework": "^6.2",
"laravel/tinker": "^1.0",

625
composer.lock generated
View File

@ -4,8 +4,61 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "296edd47be052b3885c3e2af9c84594f",
"content-hash": "df7c66ba4064ec59524f9b43a6a0d60a",
"packages": [
{
"name": "cboden/ratchet",
"version": "v0.4.2",
"source": {
"type": "git",
"url": "https://github.com/ratchetphp/Ratchet.git",
"reference": "57721e1f184f9e29378fc5363867c47ddda743fd"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ratchetphp/Ratchet/zipball/57721e1f184f9e29378fc5363867c47ddda743fd",
"reference": "57721e1f184f9e29378fc5363867c47ddda743fd",
"shasum": ""
},
"require": {
"guzzlehttp/psr7": "^1.0",
"php": ">=5.4.2",
"ratchet/rfc6455": "^0.2",
"react/socket": "^1.0 || ^0.8 || ^0.7 || ^0.6 || ^0.5",
"symfony/http-foundation": "^2.6|^3.0|^4.0|^5.0",
"symfony/routing": "^2.6|^3.0|^4.0|^5.0"
},
"require-dev": {
"phpunit/phpunit": "~4.8"
},
"type": "library",
"autoload": {
"psr-4": {
"Ratchet\\": "src/Ratchet"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Chris Boden",
"email": "cboden@gmail.com",
"role": "Developer"
}
],
"description": "PHP WebSocket library",
"homepage": "http://socketo.me",
"keywords": [
"Ratchet",
"WebSockets",
"server",
"sockets",
"websocket"
],
"time": "2020-01-27T23:08:40+00:00"
},
{
"name": "dnoegel/php-xdg-base-dir",
"version": "v0.1.1",
@ -326,6 +379,49 @@
],
"time": "2019-03-17T18:48:37+00:00"
},
{
"name": "evenement/evenement",
"version": "v3.0.1",
"source": {
"type": "git",
"url": "https://github.com/igorw/evenement.git",
"reference": "531bfb9d15f8aa57454f5f0285b18bec903b8fb7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/igorw/evenement/zipball/531bfb9d15f8aa57454f5f0285b18bec903b8fb7",
"reference": "531bfb9d15f8aa57454f5f0285b18bec903b8fb7",
"shasum": ""
},
"require": {
"php": ">=7.0"
},
"require-dev": {
"phpunit/phpunit": "^6.0"
},
"type": "library",
"autoload": {
"psr-0": {
"Evenement": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Igor Wiedler",
"email": "igor@wiedler.ch"
}
],
"description": "Événement is a very simple event dispatching library for PHP",
"keywords": [
"event-dispatcher",
"event-emitter"
],
"time": "2017-07-23T21:35:13+00:00"
},
{
"name": "fideloper/proxy",
"version": "4.2.1",
@ -380,6 +476,77 @@
],
"time": "2019-09-03T16:45:42+00:00"
},
{
"name": "guzzlehttp/psr7",
"version": "1.6.1",
"source": {
"type": "git",
"url": "https://github.com/guzzle/psr7.git",
"reference": "239400de7a173fe9901b9ac7c06497751f00727a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/239400de7a173fe9901b9ac7c06497751f00727a",
"reference": "239400de7a173fe9901b9ac7c06497751f00727a",
"shasum": ""
},
"require": {
"php": ">=5.4.0",
"psr/http-message": "~1.0",
"ralouphie/getallheaders": "^2.0.5 || ^3.0.0"
},
"provide": {
"psr/http-message-implementation": "1.0"
},
"require-dev": {
"ext-zlib": "*",
"phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8"
},
"suggest": {
"zendframework/zend-httphandlerrunner": "Emit PSR-7 responses"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.6-dev"
}
},
"autoload": {
"psr-4": {
"GuzzleHttp\\Psr7\\": "src/"
},
"files": [
"src/functions_include.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
},
{
"name": "Tobias Schultze",
"homepage": "https://github.com/Tobion"
}
],
"description": "PSR-7 message implementation that also provides common utility methods",
"keywords": [
"http",
"message",
"psr-7",
"request",
"response",
"stream",
"uri",
"url"
],
"time": "2019-07-01T23:21:34+00:00"
},
{
"name": "jakub-onderka/php-console-color",
"version": "v0.2",
@ -1556,6 +1723,56 @@
],
"time": "2017-02-14T16:28:37+00:00"
},
{
"name": "psr/http-message",
"version": "1.0.1",
"source": {
"type": "git",
"url": "https://github.com/php-fig/http-message.git",
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Http\\Message\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common interface for HTTP messages",
"homepage": "https://github.com/php-fig/http-message",
"keywords": [
"http",
"http-message",
"psr",
"psr-7",
"request",
"response"
],
"time": "2016-08-06T14:39:51+00:00"
},
{
"name": "psr/log",
"version": "1.1.2",
@ -1725,6 +1942,46 @@
],
"time": "2019-12-06T14:19:43+00:00"
},
{
"name": "ralouphie/getallheaders",
"version": "3.0.3",
"source": {
"type": "git",
"url": "https://github.com/ralouphie/getallheaders.git",
"reference": "120b605dfeb996808c31b6477290a714d356e822"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822",
"reference": "120b605dfeb996808c31b6477290a714d356e822",
"shasum": ""
},
"require": {
"php": ">=5.6"
},
"require-dev": {
"php-coveralls/php-coveralls": "^2.1",
"phpunit/phpunit": "^5 || ^6.5"
},
"type": "library",
"autoload": {
"files": [
"src/getallheaders.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Ralph Khattar",
"email": "ralph.khattar@gmail.com"
}
],
"description": "A polyfill for getallheaders.",
"time": "2019-03-08T08:55:37+00:00"
},
{
"name": "ramsey/uuid",
"version": "3.9.1",
@ -1812,6 +2069,372 @@
],
"time": "2019-12-01T04:55:27+00:00"
},
{
"name": "ratchet/rfc6455",
"version": "v0.2.6",
"source": {
"type": "git",
"url": "https://github.com/ratchetphp/RFC6455.git",
"reference": "879e48c840f8dbc296d68d6a5030673df79bd916"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ratchetphp/RFC6455/zipball/879e48c840f8dbc296d68d6a5030673df79bd916",
"reference": "879e48c840f8dbc296d68d6a5030673df79bd916",
"shasum": ""
},
"require": {
"guzzlehttp/psr7": "^1.0",
"php": ">=5.4.2"
},
"require-dev": {
"phpunit/phpunit": "4.8.*",
"react/socket": "^1.3"
},
"type": "library",
"autoload": {
"psr-4": {
"Ratchet\\RFC6455\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Chris Boden",
"email": "cboden@gmail.com",
"role": "Developer"
}
],
"description": "RFC6455 WebSocket protocol handler",
"homepage": "http://socketo.me",
"keywords": [
"WebSockets",
"rfc6455",
"websocket"
],
"time": "2019-12-15T10:18:18+00:00"
},
{
"name": "react/cache",
"version": "v1.0.0",
"source": {
"type": "git",
"url": "https://github.com/reactphp/cache.git",
"reference": "aa10d63a1b40a36a486bdf527f28bac607ee6466"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/reactphp/cache/zipball/aa10d63a1b40a36a486bdf527f28bac607ee6466",
"reference": "aa10d63a1b40a36a486bdf527f28bac607ee6466",
"shasum": ""
},
"require": {
"php": ">=5.3.0",
"react/promise": "~2.0|~1.1"
},
"require-dev": {
"phpunit/phpunit": "^6.4 || ^5.7 || ^4.8.35"
},
"type": "library",
"autoload": {
"psr-4": {
"React\\Cache\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Async, Promise-based cache interface for ReactPHP",
"keywords": [
"cache",
"caching",
"promise",
"reactphp"
],
"time": "2019-07-11T13:45:28+00:00"
},
{
"name": "react/dns",
"version": "v1.2.0",
"source": {
"type": "git",
"url": "https://github.com/reactphp/dns.git",
"reference": "a214d90c2884dac18d0cac6176202f247b66d762"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/reactphp/dns/zipball/a214d90c2884dac18d0cac6176202f247b66d762",
"reference": "a214d90c2884dac18d0cac6176202f247b66d762",
"shasum": ""
},
"require": {
"php": ">=5.3.0",
"react/cache": "^1.0 || ^0.6 || ^0.5",
"react/event-loop": "^1.0 || ^0.5",
"react/promise": "^2.7 || ^1.2.1",
"react/promise-timer": "^1.2"
},
"require-dev": {
"clue/block-react": "^1.2",
"phpunit/phpunit": "^7.0 || ^6.4 || ^5.7 || ^4.8.35"
},
"type": "library",
"autoload": {
"psr-4": {
"React\\Dns\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Async DNS resolver for ReactPHP",
"keywords": [
"async",
"dns",
"dns-resolver",
"reactphp"
],
"time": "2019-08-15T09:06:31+00:00"
},
{
"name": "react/event-loop",
"version": "v1.1.1",
"source": {
"type": "git",
"url": "https://github.com/reactphp/event-loop.git",
"reference": "6d24de090cd59cfc830263cfba965be77b563c13"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/reactphp/event-loop/zipball/6d24de090cd59cfc830263cfba965be77b563c13",
"reference": "6d24de090cd59cfc830263cfba965be77b563c13",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"require-dev": {
"phpunit/phpunit": "^7.0 || ^6.4 || ^5.7 || ^4.8.35"
},
"suggest": {
"ext-event": "~1.0 for ExtEventLoop",
"ext-pcntl": "For signal handling support when using the StreamSelectLoop",
"ext-uv": "* for ExtUvLoop"
},
"type": "library",
"autoload": {
"psr-4": {
"React\\EventLoop\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "ReactPHP's core reactor event loop that libraries can use for evented I/O.",
"keywords": [
"asynchronous",
"event-loop"
],
"time": "2020-01-01T18:39:52+00:00"
},
{
"name": "react/promise",
"version": "v2.7.1",
"source": {
"type": "git",
"url": "https://github.com/reactphp/promise.git",
"reference": "31ffa96f8d2ed0341a57848cbb84d88b89dd664d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/reactphp/promise/zipball/31ffa96f8d2ed0341a57848cbb84d88b89dd664d",
"reference": "31ffa96f8d2ed0341a57848cbb84d88b89dd664d",
"shasum": ""
},
"require": {
"php": ">=5.4.0"
},
"require-dev": {
"phpunit/phpunit": "~4.8"
},
"type": "library",
"autoload": {
"psr-4": {
"React\\Promise\\": "src/"
},
"files": [
"src/functions_include.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jan Sorgalla",
"email": "jsorgalla@gmail.com"
}
],
"description": "A lightweight implementation of CommonJS Promises/A for PHP",
"keywords": [
"promise",
"promises"
],
"time": "2019-01-07T21:25:54+00:00"
},
{
"name": "react/promise-timer",
"version": "v1.5.1",
"source": {
"type": "git",
"url": "https://github.com/reactphp/promise-timer.git",
"reference": "35fb910604fd86b00023fc5cda477c8074ad0abc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/reactphp/promise-timer/zipball/35fb910604fd86b00023fc5cda477c8074ad0abc",
"reference": "35fb910604fd86b00023fc5cda477c8074ad0abc",
"shasum": ""
},
"require": {
"php": ">=5.3",
"react/event-loop": "^1.0 || ^0.5 || ^0.4 || ^0.3.5",
"react/promise": "^2.7.0 || ^1.2.1"
},
"require-dev": {
"phpunit/phpunit": "^6.4 || ^5.7 || ^4.8.35"
},
"type": "library",
"autoload": {
"psr-4": {
"React\\Promise\\Timer\\": "src/"
},
"files": [
"src/functions_include.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Christian Lück",
"email": "christian@lueck.tv"
}
],
"description": "A trivial implementation of timeouts for Promises, built on top of ReactPHP.",
"homepage": "https://github.com/reactphp/promise-timer",
"keywords": [
"async",
"event-loop",
"promise",
"reactphp",
"timeout",
"timer"
],
"time": "2019-03-27T18:10:32+00:00"
},
{
"name": "react/socket",
"version": "v1.3.0",
"source": {
"type": "git",
"url": "https://github.com/reactphp/socket.git",
"reference": "10f0629ec83ea0fa22597f348623f554227e3ca0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/reactphp/socket/zipball/10f0629ec83ea0fa22597f348623f554227e3ca0",
"reference": "10f0629ec83ea0fa22597f348623f554227e3ca0",
"shasum": ""
},
"require": {
"evenement/evenement": "^3.0 || ^2.0 || ^1.0",
"php": ">=5.3.0",
"react/dns": "^1.0 || ^0.4.13",
"react/event-loop": "^1.0 || ^0.5 || ^0.4 || ^0.3.5",
"react/promise": "^2.6.0 || ^1.2.1",
"react/promise-timer": "^1.4.0",
"react/stream": "^1.1"
},
"require-dev": {
"clue/block-react": "^1.2",
"phpunit/phpunit": "^6.4 || ^5.7 || ^4.8.35"
},
"type": "library",
"autoload": {
"psr-4": {
"React\\Socket\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Async, streaming plaintext TCP/IP and secure TLS socket server and client connections for ReactPHP",
"keywords": [
"Connection",
"Socket",
"async",
"reactphp",
"stream"
],
"time": "2019-07-10T10:11:14+00:00"
},
{
"name": "react/stream",
"version": "v1.1.0",
"source": {
"type": "git",
"url": "https://github.com/reactphp/stream.git",
"reference": "50426855f7a77ddf43b9266c22320df5bf6c6ce6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/reactphp/stream/zipball/50426855f7a77ddf43b9266c22320df5bf6c6ce6",
"reference": "50426855f7a77ddf43b9266c22320df5bf6c6ce6",
"shasum": ""
},
"require": {
"evenement/evenement": "^3.0 || ^2.0 || ^1.0",
"php": ">=5.3.8",
"react/event-loop": "^1.0 || ^0.5 || ^0.4 || ^0.3.5"
},
"require-dev": {
"clue/stream-filter": "~1.2",
"phpunit/phpunit": "^6.4 || ^5.7 || ^4.8.35"
},
"type": "library",
"autoload": {
"psr-4": {
"React\\Stream\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Event-driven readable and writable streams for non-blocking I/O in ReactPHP",
"keywords": [
"event-driven",
"io",
"non-blocking",
"pipe",
"reactphp",
"readable",
"stream",
"writable"
],
"time": "2019-01-01T16:15:09+00:00"
},
{
"name": "swiftmailer/swiftmailer",
"version": "v6.2.3",