diff options
author | Marvin Borner | 2018-08-27 00:47:26 +0200 |
---|---|---|
committer | Marvin Borner | 2018-08-27 00:47:26 +0200 |
commit | 06031351cf00986e7c2118ddcf892fa1c7e7234e (patch) | |
tree | 801754cc06cc853c9a0a59761bf81705871ff17d | |
parent | d18377e2f3d5506775e78d9b5557162f710c65b5 (diff) |
Added basic websocket service
-rw-r--r-- | composer.json | 3 | ||||
-rw-r--r-- | composer.lock | 465 | ||||
-rw-r--r-- | infrastructure/Console/Commands/WebSocketServerCommand.php | 38 | ||||
-rw-r--r-- | infrastructure/Console/Kernel.php | 3 | ||||
-rw-r--r-- | infrastructure/Http/WebSocketController.php | 56 |
5 files changed, 562 insertions, 3 deletions
diff --git a/composer.json b/composer.json index 5c2395d..68dd889 100644 --- a/composer.json +++ b/composer.json @@ -14,7 +14,8 @@ "optimus/heimdal": "~1.0", "laravel/passport": "^3.0", "optimus/api-consumer": "0.2.*", - "predis/predis": "^1.1" + "predis/predis": "^1.1", + "cboden/ratchet": "^0.4.1" }, "require-dev": { "fzaninotto/faker": "~1.4", diff --git a/composer.lock b/composer.lock index 9c92533..bc159b2 100644 --- a/composer.lock +++ b/composer.lock @@ -4,9 +4,62 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "ae6edddcc81e8a8624df708fe2d51b0f", + "content-hash": "c9eec2fc20475cd39d0ae185629db619", "packages": [ { + "name": "cboden/ratchet", + "version": "v0.4.1", + "source": { + "type": "git", + "url": "https://github.com/ratchetphp/Ratchet.git", + "reference": "0d31f3a8ad4795fd48397712709e55cd07f51360" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ratchetphp/Ratchet/zipball/0d31f3a8ad4795fd48397712709e55cd07f51360", + "reference": "0d31f3a8ad4795fd48397712709e55cd07f51360", + "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", + "symfony/routing": "^2.6|^3.0|^4.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": "2017-12-12T00:49:31+00:00" + }, + { "name": "defuse/php-encryption", "version": "v2.2.1", "source": { @@ -183,6 +236,49 @@ "time": "2018-03-08T01:11:30+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": "firebase/php-jwt", "version": "v4.0.0", "source": { @@ -1635,6 +1731,373 @@ "time": "2018-07-19T23:38:55+00:00" }, { + "name": "ratchet/rfc6455", + "version": "0.2.4", + "source": { + "type": "git", + "url": "https://github.com/ratchetphp/RFC6455.git", + "reference": "1612f528c3496ad06e910d0f8b6f16ab97696706" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ratchetphp/RFC6455/zipball/1612f528c3496ad06e910d0f8b6f16ab97696706", + "reference": "1612f528c3496ad06e910d0f8b6f16ab97696706", + "shasum": "" + }, + "require": { + "guzzlehttp/psr7": "^1.0", + "php": ">=5.4.2" + }, + "require-dev": { + "phpunit/phpunit": "4.8.*", + "react/http": "^0.4.1", + "react/socket-client": "^0.4.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": "2018-05-02T14:52:00+00:00" + }, + { + "name": "react/cache", + "version": "v0.5.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/cache.git", + "reference": "7d7da7fb7574d471904ba357b39bbf110ccdbf66" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/cache/zipball/7d7da7fb7574d471904ba357b39bbf110ccdbf66", + "reference": "7d7da7fb7574d471904ba357b39bbf110ccdbf66", + "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": "2018-06-25T12:52:40+00:00" + }, + { + "name": "react/dns", + "version": "v0.4.15", + "source": { + "type": "git", + "url": "https://github.com/reactphp/dns.git", + "reference": "319e110a436d26a2fa137cfa3ef2063951715794" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/dns/zipball/319e110a436d26a2fa137cfa3ef2063951715794", + "reference": "319e110a436d26a2fa137cfa3ef2063951715794", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "react/cache": "^0.5 || ^0.4 || ^0.3", + "react/event-loop": "^1.0 || ^0.5 || ^0.4 || ^0.3.5", + "react/promise": "^2.1 || ^1.2.1", + "react/promise-timer": "^1.2", + "react/stream": "^1.0 || ^0.7 || ^0.6 || ^0.5 || ^0.4.5" + }, + "require-dev": { + "clue/block-react": "^1.2", + "phpunit/phpunit": "^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": "2018-07-02T12:17:56+00:00" + }, + { + "name": "react/event-loop", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/event-loop.git", + "reference": "0266aff7aa7b0613b1f38a723e14a0ebc55cfca3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/event-loop/zipball/0266aff7aa7b0613b1f38a723e14a0ebc55cfca3", + "reference": "0266aff7aa7b0613b1f38a723e14a0ebc55cfca3", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.8.35 || ^5.7 || ^6.4" + }, + "suggest": { + "ext-event": "~1.0 for ExtEventLoop", + "ext-pcntl": "For signal handling support when using the StreamSelectLoop" + }, + "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": "2018-07-11T14:37:46+00:00" + }, + { + "name": "react/promise", + "version": "v2.7.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/promise.git", + "reference": "f4edc2581617431aea50430749db55cc3fc031b3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/promise/zipball/f4edc2581617431aea50430749db55cc3fc031b3", + "reference": "f4edc2581617431aea50430749db55cc3fc031b3", + "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": "2018-06-13T15:59:06+00:00" + }, + { + "name": "react/promise-timer", + "version": "v1.5.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/promise-timer.git", + "reference": "a11206938ca2394dc7bb368f5da25cd4533fa603" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/promise-timer/zipball/a11206938ca2394dc7bb368f5da25cd4533fa603", + "reference": "a11206938ca2394dc7bb368f5da25cd4533fa603", + "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.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": "2018-06-13T16:45:37+00:00" + }, + { + "name": "react/socket", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/socket.git", + "reference": "476e2644a634c6301b8111e6d22a61679e6e6bd0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/socket/zipball/476e2644a634c6301b8111e6d22a61679e6e6bd0", + "reference": "476e2644a634c6301b8111e6d22a61679e6e6bd0", + "shasum": "" + }, + "require": { + "evenement/evenement": "^3.0 || ^2.0 || ^1.0", + "php": ">=5.3.0", + "react/dns": "^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.0 || ^0.7.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": "2018-07-11T14:38:22+00:00" + }, + { + "name": "react/stream", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/stream.git", + "reference": "fdd0140f42805d65bf9687636503db0b326d2244" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/stream/zipball/fdd0140f42805d65bf9687636503db0b326d2244", + "reference": "fdd0140f42805d65bf9687636503db0b326d2244", + "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": "2018-07-11T14:38:16+00:00" + }, + { "name": "sentry/sentry", "version": "1.9.2", "source": { diff --git a/infrastructure/Console/Commands/WebSocketServerCommand.php b/infrastructure/Console/Commands/WebSocketServerCommand.php new file mode 100644 index 0000000..4723b29 --- /dev/null +++ b/infrastructure/Console/Commands/WebSocketServerCommand.php @@ -0,0 +1,38 @@ +<?php + +namespace Infrastructure\Console\Commands; + +use Illuminate\Console\Command; +use Infrastructure\Http\WebSocketController; +use Ratchet\Http\HttpServer; +use Ratchet\Server\IoServer; +use Ratchet\WebSocket\WsServer; + +class WebSocketServerCommand extends Command +{ + /** + * The console command name. + * + * @var string + */ + protected $name = 'websocket'; + + /** + * Execute the console command. + * + * @return void + */ + public function fire() + { + $server = IoServer::factory( + new HttpServer( + new WsServer( + new WebSocketController() + ) + ), + 1337 + ); + $this->line('Started server.'); + $server->run(); + } +}
\ No newline at end of file diff --git a/infrastructure/Console/Kernel.php b/infrastructure/Console/Kernel.php index dffc73a..13329ae 100644 --- a/infrastructure/Console/Kernel.php +++ b/infrastructure/Console/Kernel.php @@ -14,7 +14,8 @@ class Kernel extends ConsoleKernel * @var array */ protected $commands = [ - AddUserCommand::class + AddUserCommand::class, + Commands\WebSocketServerCommand::class ]; /** diff --git a/infrastructure/Http/WebSocketController.php b/infrastructure/Http/WebSocketController.php new file mode 100644 index 0000000..19e0868 --- /dev/null +++ b/infrastructure/Http/WebSocketController.php @@ -0,0 +1,56 @@ +<?php + +namespace Infrastructure\Http; + +use Ratchet\ConnectionInterface; +use Ratchet\MessageComponentInterface; + +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]); + } + + /** + * 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) + { + 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) + { + + } +}
\ No newline at end of file |