├── .gitignore
├── LICENSE
├── README.md
├── composer.json
├── composer.lock
├── src
├── Console
│ └── Commands
│ │ └── RatchetServerCommand.php
├── Examples
│ └── Pusher.php
├── Providers
│ └── LaravelRatchetServiceProvider.php
├── RatchetWampServer.php
├── RatchetWsServer.php
├── config
│ └── ratchet.php
└── lang
│ └── en
│ └── messages.php
└── tests
├── index.js
└── pubsub.html
/.gitignore:
--------------------------------------------------------------------------------
1 | vendor/
2 | node_modules/
3 |
4 | # Laravel 4 specific
5 | bootstrap/compiled.php
6 | app/storage/
7 |
8 | # Laravel 5 & Lumen specific
9 | bootstrap/cache/
10 | storage/
11 | .env.*.php
12 | .env.php
13 | .env
14 | .env.example
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Askedio
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Laravel Ratchet Server
2 |
3 | This package enables you to create and run a fully functioning WebSocket server in your Laravel app. It can optionally receive messages broadcast over ZeroMQ.
4 |
5 | ## Requirements
6 |
7 | - PHP 7.1+
8 | - Laravel 5.5+
9 | - ZeroMQ
10 | - ext-zmq for PHP
11 |
12 | ## Installation
13 |
14 | ```bash
15 | $ composer require askedio/laravel-ratchet
16 | ```
17 |
18 | The service provider is loaded automatically in Laravel 5.5 using Package Autodiscovery.
19 |
20 | Publish the vendor files so you can configure your server defaults.
21 |
22 | ```bash
23 | $ php artisan vendor:publish --provider="Askedio\LaravelRatchet\Providers\LaravelRatchetServiceProvider"
24 | ```
25 |
26 | ## Starting the Server
27 |
28 | After completing installation, the quickest way to start a standard WebSocket server is simply by running:
29 |
30 | ```bash
31 | $ php artisan ratchet:serve --driver=WsServer
32 | ```
33 |
34 | This will run a simple example server based on `src/Examples/Pusher.php`.
35 |
36 | It's possible to create a WampServer or an IoServer also. Use the `--help` switch on the command to find out more.
37 |
38 | You should create your own server class inside your `app` folder by extending one of the core Ratchet server classes: [RatchetWsServer.php](https://github.com/Askedio/laravel-ratchet/blob/master/src/RatchetWsServer.php) or [RatchetWampServer.php](https://github.com/Askedio/laravel-ratchet/blob/master/src/RatchetWampServer.php).
39 |
40 | Then update your `config/ratchet.php` file to point to your server `class`.
41 |
42 | ## Use with Laravel Broadcasting
43 |
44 | To use broadcasting in your Laravel app with the server you create, you will need a ZeroMQ broadcast driver for Laravel (e.g. [this one](https://github.com/pelim/laravel-zmq)).
45 |
46 | You will also need to tell your Ratchet server to bind to a ZeroMQ socket. You can do this simply by passing the `-z` option, i.e.:
47 |
48 | ```bash
49 | $ php artisan ratchet:serve --driver=WsServer -z
50 | ```
51 |
52 | This will connect to the socket you define in your `config/ratchet.php` settings and listen for messages from ZeroMQ.
53 |
54 | To handle messages published via ZeroMQ, simply add a `public function onEntry($messages)` method to your server class. This will allow you to receive messages inside your Ratchet server instance and determine how to route them.
55 |
56 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "askedio/laravel-ratchet",
3 | "description": "A Ratchet Server built for Laravel",
4 | "keywords": ["laravel"],
5 | "license": "MIT",
6 | "type": "library",
7 | "require": {
8 | "php": ">=7.2.0",
9 | "ext-zmq": "*",
10 | "cboden/ratchet": "^0.4",
11 | "graham-campbell/throttle": "^7.4",
12 | "illuminate/console": "^6.0",
13 | "illuminate/support": "^6.0",
14 | "react/zmq": "0.2.*|0.3.*|0.4.*"
15 | },
16 | "autoload": {
17 | "psr-4": {
18 | "Askedio\\LaravelRatchet\\": "src/"
19 | }
20 | },
21 | "extra": {
22 | "laravel": {
23 | "providers": [
24 | "Askedio\\LaravelRatchet\\Providers\\LaravelRatchetServiceProvider"
25 | ]
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/composer.lock:
--------------------------------------------------------------------------------
1 | {
2 | "_readme": [
3 | "This file locks the dependencies of your project to a known state",
4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
5 | "This file is @generated automatically"
6 | ],
7 | "content-hash": "ec4e3bee67df5cae24dda4a2ad9492ef",
8 | "packages": [
9 | {
10 | "name": "cboden/ratchet",
11 | "version": "v0.4.1",
12 | "source": {
13 | "type": "git",
14 | "url": "https://github.com/ratchetphp/Ratchet.git",
15 | "reference": "0d31f3a8ad4795fd48397712709e55cd07f51360"
16 | },
17 | "dist": {
18 | "type": "zip",
19 | "url": "https://api.github.com/repos/ratchetphp/Ratchet/zipball/0d31f3a8ad4795fd48397712709e55cd07f51360",
20 | "reference": "0d31f3a8ad4795fd48397712709e55cd07f51360",
21 | "shasum": ""
22 | },
23 | "require": {
24 | "guzzlehttp/psr7": "^1.0",
25 | "php": ">=5.4.2",
26 | "ratchet/rfc6455": "^0.2",
27 | "react/socket": "^1.0 || ^0.8 || ^0.7 || ^0.6 || ^0.5",
28 | "symfony/http-foundation": "^2.6|^3.0|^4.0",
29 | "symfony/routing": "^2.6|^3.0|^4.0"
30 | },
31 | "require-dev": {
32 | "phpunit/phpunit": "~4.8"
33 | },
34 | "type": "library",
35 | "autoload": {
36 | "psr-4": {
37 | "Ratchet\\": "src/Ratchet"
38 | }
39 | },
40 | "notification-url": "https://packagist.org/downloads/",
41 | "license": [
42 | "MIT"
43 | ],
44 | "authors": [
45 | {
46 | "name": "Chris Boden",
47 | "email": "cboden@gmail.com",
48 | "role": "Developer"
49 | }
50 | ],
51 | "description": "PHP WebSocket library",
52 | "homepage": "http://socketo.me",
53 | "keywords": [
54 | "Ratchet",
55 | "WebSockets",
56 | "server",
57 | "sockets",
58 | "websocket"
59 | ],
60 | "time": "2017-12-12T00:49:31+00:00"
61 | },
62 | {
63 | "name": "doctrine/inflector",
64 | "version": "v1.3.0",
65 | "source": {
66 | "type": "git",
67 | "url": "https://github.com/doctrine/inflector.git",
68 | "reference": "5527a48b7313d15261292c149e55e26eae771b0a"
69 | },
70 | "dist": {
71 | "type": "zip",
72 | "url": "https://api.github.com/repos/doctrine/inflector/zipball/5527a48b7313d15261292c149e55e26eae771b0a",
73 | "reference": "5527a48b7313d15261292c149e55e26eae771b0a",
74 | "shasum": ""
75 | },
76 | "require": {
77 | "php": "^7.1"
78 | },
79 | "require-dev": {
80 | "phpunit/phpunit": "^6.2"
81 | },
82 | "type": "library",
83 | "extra": {
84 | "branch-alias": {
85 | "dev-master": "1.3.x-dev"
86 | }
87 | },
88 | "autoload": {
89 | "psr-4": {
90 | "Doctrine\\Common\\Inflector\\": "lib/Doctrine/Common/Inflector"
91 | }
92 | },
93 | "notification-url": "https://packagist.org/downloads/",
94 | "license": [
95 | "MIT"
96 | ],
97 | "authors": [
98 | {
99 | "name": "Roman Borschel",
100 | "email": "roman@code-factory.org"
101 | },
102 | {
103 | "name": "Benjamin Eberlei",
104 | "email": "kontakt@beberlei.de"
105 | },
106 | {
107 | "name": "Guilherme Blanco",
108 | "email": "guilhermeblanco@gmail.com"
109 | },
110 | {
111 | "name": "Jonathan Wage",
112 | "email": "jonwage@gmail.com"
113 | },
114 | {
115 | "name": "Johannes Schmitt",
116 | "email": "schmittjoh@gmail.com"
117 | }
118 | ],
119 | "description": "Common String Manipulations with regard to casing and singular/plural rules.",
120 | "homepage": "http://www.doctrine-project.org",
121 | "keywords": [
122 | "inflection",
123 | "pluralize",
124 | "singularize",
125 | "string"
126 | ],
127 | "time": "2018-01-09T20:05:19+00:00"
128 | },
129 | {
130 | "name": "evenement/evenement",
131 | "version": "v2.1.0",
132 | "source": {
133 | "type": "git",
134 | "url": "https://github.com/igorw/evenement.git",
135 | "reference": "6ba9a777870ab49f417e703229d53931ed40fd7a"
136 | },
137 | "dist": {
138 | "type": "zip",
139 | "url": "https://api.github.com/repos/igorw/evenement/zipball/6ba9a777870ab49f417e703229d53931ed40fd7a",
140 | "reference": "6ba9a777870ab49f417e703229d53931ed40fd7a",
141 | "shasum": ""
142 | },
143 | "require": {
144 | "php": ">=5.4.0"
145 | },
146 | "require-dev": {
147 | "phpunit/phpunit": "^6.0||^5.7||^4.8.35"
148 | },
149 | "type": "library",
150 | "extra": {
151 | "branch-alias": {
152 | "dev-master": "2.0-dev"
153 | }
154 | },
155 | "autoload": {
156 | "psr-0": {
157 | "Evenement": "src"
158 | }
159 | },
160 | "notification-url": "https://packagist.org/downloads/",
161 | "license": [
162 | "MIT"
163 | ],
164 | "authors": [
165 | {
166 | "name": "Igor Wiedler",
167 | "email": "igor@wiedler.ch"
168 | }
169 | ],
170 | "description": "Événement is a very simple event dispatching library for PHP",
171 | "keywords": [
172 | "event-dispatcher",
173 | "event-emitter"
174 | ],
175 | "time": "2017-07-17T17:39:19+00:00"
176 | },
177 | {
178 | "name": "graham-campbell/throttle",
179 | "version": "v7.1.0",
180 | "source": {
181 | "type": "git",
182 | "url": "https://github.com/GrahamCampbell/Laravel-Throttle.git",
183 | "reference": "76b06d5c967fac1e9893cccd923e310961bae7b2"
184 | },
185 | "dist": {
186 | "type": "zip",
187 | "url": "https://api.github.com/repos/GrahamCampbell/Laravel-Throttle/zipball/76b06d5c967fac1e9893cccd923e310961bae7b2",
188 | "reference": "76b06d5c967fac1e9893cccd923e310961bae7b2",
189 | "shasum": ""
190 | },
191 | "require": {
192 | "illuminate/cache": "5.5.*|5.6.*|5.7.*",
193 | "illuminate/contracts": "5.5.*|5.6.*|5.7.*",
194 | "illuminate/http": "5.5.*|5.6.*|5.7.*",
195 | "illuminate/support": "5.5.*|5.6.*|5.7.*",
196 | "php": "^7.1.3"
197 | },
198 | "require-dev": {
199 | "graham-campbell/analyzer": "^2.1",
200 | "graham-campbell/testbench": "^5.1",
201 | "mockery/mockery": "^1.0",
202 | "phpunit/phpunit": "^6.5|^7.0"
203 | },
204 | "type": "library",
205 | "extra": {
206 | "branch-alias": {
207 | "dev-master": "7.1-dev"
208 | },
209 | "laravel": {
210 | "providers": [
211 | "GrahamCampbell\\Throttle\\ThrottleServiceProvider"
212 | ]
213 | }
214 | },
215 | "autoload": {
216 | "psr-4": {
217 | "GrahamCampbell\\Throttle\\": "src/"
218 | }
219 | },
220 | "notification-url": "https://packagist.org/downloads/",
221 | "license": [
222 | "MIT"
223 | ],
224 | "authors": [
225 | {
226 | "name": "Graham Campbell",
227 | "email": "graham@alt-three.com"
228 | }
229 | ],
230 | "description": "Throttle Is A Rate Limiter For Laravel 5",
231 | "keywords": [
232 | "Graham Campbell",
233 | "GrahamCampbell",
234 | "Laravel Throttle",
235 | "Laravel-Throttle",
236 | "framework",
237 | "laravel",
238 | "rate limit",
239 | "throttle",
240 | "throttling"
241 | ],
242 | "time": "2018-08-23T12:18:33+00:00"
243 | },
244 | {
245 | "name": "guzzlehttp/psr7",
246 | "version": "1.4.2",
247 | "source": {
248 | "type": "git",
249 | "url": "https://github.com/guzzle/psr7.git",
250 | "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c"
251 | },
252 | "dist": {
253 | "type": "zip",
254 | "url": "https://api.github.com/repos/guzzle/psr7/zipball/f5b8a8512e2b58b0071a7280e39f14f72e05d87c",
255 | "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c",
256 | "shasum": ""
257 | },
258 | "require": {
259 | "php": ">=5.4.0",
260 | "psr/http-message": "~1.0"
261 | },
262 | "provide": {
263 | "psr/http-message-implementation": "1.0"
264 | },
265 | "require-dev": {
266 | "phpunit/phpunit": "~4.0"
267 | },
268 | "type": "library",
269 | "extra": {
270 | "branch-alias": {
271 | "dev-master": "1.4-dev"
272 | }
273 | },
274 | "autoload": {
275 | "psr-4": {
276 | "GuzzleHttp\\Psr7\\": "src/"
277 | },
278 | "files": [
279 | "src/functions_include.php"
280 | ]
281 | },
282 | "notification-url": "https://packagist.org/downloads/",
283 | "license": [
284 | "MIT"
285 | ],
286 | "authors": [
287 | {
288 | "name": "Michael Dowling",
289 | "email": "mtdowling@gmail.com",
290 | "homepage": "https://github.com/mtdowling"
291 | },
292 | {
293 | "name": "Tobias Schultze",
294 | "homepage": "https://github.com/Tobion"
295 | }
296 | ],
297 | "description": "PSR-7 message implementation that also provides common utility methods",
298 | "keywords": [
299 | "http",
300 | "message",
301 | "request",
302 | "response",
303 | "stream",
304 | "uri",
305 | "url"
306 | ],
307 | "time": "2017-03-20T17:10:46+00:00"
308 | },
309 | {
310 | "name": "illuminate/cache",
311 | "version": "v5.7.1",
312 | "source": {
313 | "type": "git",
314 | "url": "https://github.com/illuminate/cache.git",
315 | "reference": "0d416c93433e1473b96bffe0acb25271b876eb5e"
316 | },
317 | "dist": {
318 | "type": "zip",
319 | "url": "https://api.github.com/repos/illuminate/cache/zipball/0d416c93433e1473b96bffe0acb25271b876eb5e",
320 | "reference": "0d416c93433e1473b96bffe0acb25271b876eb5e",
321 | "shasum": ""
322 | },
323 | "require": {
324 | "illuminate/contracts": "5.7.*",
325 | "illuminate/support": "5.7.*",
326 | "php": "^7.1.3"
327 | },
328 | "suggest": {
329 | "illuminate/database": "Required to use the database cache driver (5.7.*).",
330 | "illuminate/filesystem": "Required to use the file cache driver (5.7.*).",
331 | "illuminate/redis": "Required to use the redis cache driver (5.7.*)."
332 | },
333 | "type": "library",
334 | "extra": {
335 | "branch-alias": {
336 | "dev-master": "5.7-dev"
337 | }
338 | },
339 | "autoload": {
340 | "psr-4": {
341 | "Illuminate\\Cache\\": ""
342 | }
343 | },
344 | "notification-url": "https://packagist.org/downloads/",
345 | "license": [
346 | "MIT"
347 | ],
348 | "authors": [
349 | {
350 | "name": "Taylor Otwell",
351 | "email": "taylor@laravel.com"
352 | }
353 | ],
354 | "description": "The Illuminate Cache package.",
355 | "homepage": "https://laravel.com",
356 | "time": "2018-08-26T13:50:36+00:00"
357 | },
358 | {
359 | "name": "illuminate/console",
360 | "version": "v5.7.1",
361 | "source": {
362 | "type": "git",
363 | "url": "https://github.com/illuminate/console.git",
364 | "reference": "aeac0d059af9b3dc856831d4b82e6539a3454b32"
365 | },
366 | "dist": {
367 | "type": "zip",
368 | "url": "https://api.github.com/repos/illuminate/console/zipball/aeac0d059af9b3dc856831d4b82e6539a3454b32",
369 | "reference": "aeac0d059af9b3dc856831d4b82e6539a3454b32",
370 | "shasum": ""
371 | },
372 | "require": {
373 | "illuminate/contracts": "5.7.*",
374 | "illuminate/support": "5.7.*",
375 | "php": "^7.1.3",
376 | "symfony/console": "^4.1"
377 | },
378 | "suggest": {
379 | "dragonmantank/cron-expression": "Required to use scheduling component (^2.0).",
380 | "guzzlehttp/guzzle": "Required to use the ping methods on schedules (^6.0).",
381 | "symfony/process": "Required to use scheduling component (^4.1)."
382 | },
383 | "type": "library",
384 | "extra": {
385 | "branch-alias": {
386 | "dev-master": "5.7-dev"
387 | }
388 | },
389 | "autoload": {
390 | "psr-4": {
391 | "Illuminate\\Console\\": ""
392 | }
393 | },
394 | "notification-url": "https://packagist.org/downloads/",
395 | "license": [
396 | "MIT"
397 | ],
398 | "authors": [
399 | {
400 | "name": "Taylor Otwell",
401 | "email": "taylor@laravel.com"
402 | }
403 | ],
404 | "description": "The Illuminate Console package.",
405 | "homepage": "https://laravel.com",
406 | "time": "2018-09-04T13:13:04+00:00"
407 | },
408 | {
409 | "name": "illuminate/contracts",
410 | "version": "v5.7.1",
411 | "source": {
412 | "type": "git",
413 | "url": "https://github.com/illuminate/contracts.git",
414 | "reference": "31112aa75ef2aadb9f4e6662d6b88ecde7a3e847"
415 | },
416 | "dist": {
417 | "type": "zip",
418 | "url": "https://api.github.com/repos/illuminate/contracts/zipball/31112aa75ef2aadb9f4e6662d6b88ecde7a3e847",
419 | "reference": "31112aa75ef2aadb9f4e6662d6b88ecde7a3e847",
420 | "shasum": ""
421 | },
422 | "require": {
423 | "php": "^7.1.3",
424 | "psr/container": "^1.0",
425 | "psr/simple-cache": "^1.0"
426 | },
427 | "type": "library",
428 | "extra": {
429 | "branch-alias": {
430 | "dev-master": "5.7-dev"
431 | }
432 | },
433 | "autoload": {
434 | "psr-4": {
435 | "Illuminate\\Contracts\\": ""
436 | }
437 | },
438 | "notification-url": "https://packagist.org/downloads/",
439 | "license": [
440 | "MIT"
441 | ],
442 | "authors": [
443 | {
444 | "name": "Taylor Otwell",
445 | "email": "taylor@laravel.com"
446 | }
447 | ],
448 | "description": "The Illuminate Contracts package.",
449 | "homepage": "https://laravel.com",
450 | "time": "2018-08-31T18:58:53+00:00"
451 | },
452 | {
453 | "name": "illuminate/filesystem",
454 | "version": "v5.7.1",
455 | "source": {
456 | "type": "git",
457 | "url": "https://github.com/illuminate/filesystem.git",
458 | "reference": "2251e31e382ddcbbcb34fddc43e7cc0afa530be8"
459 | },
460 | "dist": {
461 | "type": "zip",
462 | "url": "https://api.github.com/repos/illuminate/filesystem/zipball/2251e31e382ddcbbcb34fddc43e7cc0afa530be8",
463 | "reference": "2251e31e382ddcbbcb34fddc43e7cc0afa530be8",
464 | "shasum": ""
465 | },
466 | "require": {
467 | "illuminate/contracts": "5.7.*",
468 | "illuminate/support": "5.7.*",
469 | "php": "^7.1.3",
470 | "symfony/finder": "^4.1"
471 | },
472 | "suggest": {
473 | "league/flysystem": "Required to use the Flysystem local and FTP drivers (^1.0).",
474 | "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (^1.0).",
475 | "league/flysystem-cached-adapter": "Required to use the Flysystem cache (^1.0).",
476 | "league/flysystem-rackspace": "Required to use the Flysystem Rackspace driver (^1.0).",
477 | "league/flysystem-sftp": "Required to use the Flysystem SFTP driver (^1.0)."
478 | },
479 | "type": "library",
480 | "extra": {
481 | "branch-alias": {
482 | "dev-master": "5.7-dev"
483 | }
484 | },
485 | "autoload": {
486 | "psr-4": {
487 | "Illuminate\\Filesystem\\": ""
488 | }
489 | },
490 | "notification-url": "https://packagist.org/downloads/",
491 | "license": [
492 | "MIT"
493 | ],
494 | "authors": [
495 | {
496 | "name": "Taylor Otwell",
497 | "email": "taylor@laravel.com"
498 | }
499 | ],
500 | "description": "The Illuminate Filesystem package.",
501 | "homepage": "https://laravel.com",
502 | "time": "2018-08-14T19:42:44+00:00"
503 | },
504 | {
505 | "name": "illuminate/http",
506 | "version": "v5.7.1",
507 | "source": {
508 | "type": "git",
509 | "url": "https://github.com/illuminate/http.git",
510 | "reference": "5bcf3e2d547a07bf98e0e71fa919fdaf513eee36"
511 | },
512 | "dist": {
513 | "type": "zip",
514 | "url": "https://api.github.com/repos/illuminate/http/zipball/5bcf3e2d547a07bf98e0e71fa919fdaf513eee36",
515 | "reference": "5bcf3e2d547a07bf98e0e71fa919fdaf513eee36",
516 | "shasum": ""
517 | },
518 | "require": {
519 | "illuminate/session": "5.7.*",
520 | "illuminate/support": "5.7.*",
521 | "php": "^7.1.3",
522 | "symfony/http-foundation": "^4.1",
523 | "symfony/http-kernel": "^4.1"
524 | },
525 | "type": "library",
526 | "extra": {
527 | "branch-alias": {
528 | "dev-master": "5.7-dev"
529 | }
530 | },
531 | "autoload": {
532 | "psr-4": {
533 | "Illuminate\\Http\\": ""
534 | }
535 | },
536 | "notification-url": "https://packagist.org/downloads/",
537 | "license": [
538 | "MIT"
539 | ],
540 | "authors": [
541 | {
542 | "name": "Taylor Otwell",
543 | "email": "taylor@laravel.com"
544 | }
545 | ],
546 | "description": "The Illuminate Http package.",
547 | "homepage": "https://laravel.com",
548 | "time": "2018-08-28T08:47:30+00:00"
549 | },
550 | {
551 | "name": "illuminate/session",
552 | "version": "v5.7.1",
553 | "source": {
554 | "type": "git",
555 | "url": "https://github.com/illuminate/session.git",
556 | "reference": "712f834c8b85a4f58ab40f56a359ac3e7e24c11a"
557 | },
558 | "dist": {
559 | "type": "zip",
560 | "url": "https://api.github.com/repos/illuminate/session/zipball/712f834c8b85a4f58ab40f56a359ac3e7e24c11a",
561 | "reference": "712f834c8b85a4f58ab40f56a359ac3e7e24c11a",
562 | "shasum": ""
563 | },
564 | "require": {
565 | "illuminate/contracts": "5.7.*",
566 | "illuminate/filesystem": "5.7.*",
567 | "illuminate/support": "5.7.*",
568 | "php": "^7.1.3",
569 | "symfony/finder": "^4.1",
570 | "symfony/http-foundation": "^4.1"
571 | },
572 | "suggest": {
573 | "illuminate/console": "Required to use the session:table command (5.7.*)."
574 | },
575 | "type": "library",
576 | "extra": {
577 | "branch-alias": {
578 | "dev-master": "5.7-dev"
579 | }
580 | },
581 | "autoload": {
582 | "psr-4": {
583 | "Illuminate\\Session\\": ""
584 | }
585 | },
586 | "notification-url": "https://packagist.org/downloads/",
587 | "license": [
588 | "MIT"
589 | ],
590 | "authors": [
591 | {
592 | "name": "Taylor Otwell",
593 | "email": "taylor@laravel.com"
594 | }
595 | ],
596 | "description": "The Illuminate Session package.",
597 | "homepage": "https://laravel.com",
598 | "time": "2018-07-30T13:42:51+00:00"
599 | },
600 | {
601 | "name": "illuminate/support",
602 | "version": "v5.7.1",
603 | "source": {
604 | "type": "git",
605 | "url": "https://github.com/illuminate/support.git",
606 | "reference": "800277753547b925c9442cc4f937e3daea39c1c5"
607 | },
608 | "dist": {
609 | "type": "zip",
610 | "url": "https://api.github.com/repos/illuminate/support/zipball/800277753547b925c9442cc4f937e3daea39c1c5",
611 | "reference": "800277753547b925c9442cc4f937e3daea39c1c5",
612 | "shasum": ""
613 | },
614 | "require": {
615 | "doctrine/inflector": "^1.1",
616 | "ext-mbstring": "*",
617 | "illuminate/contracts": "5.7.*",
618 | "nesbot/carbon": "^1.24.1",
619 | "php": "^7.1.3"
620 | },
621 | "conflict": {
622 | "tightenco/collect": "<5.5.33"
623 | },
624 | "suggest": {
625 | "illuminate/filesystem": "Required to use the composer class (5.7.*).",
626 | "ramsey/uuid": "Required to use Str::uuid() (^3.7).",
627 | "symfony/process": "Required to use the composer class (^4.1).",
628 | "symfony/var-dumper": "Required to use the dd function (^4.1)."
629 | },
630 | "type": "library",
631 | "extra": {
632 | "branch-alias": {
633 | "dev-master": "5.7-dev"
634 | }
635 | },
636 | "autoload": {
637 | "psr-4": {
638 | "Illuminate\\Support\\": ""
639 | },
640 | "files": [
641 | "helpers.php"
642 | ]
643 | },
644 | "notification-url": "https://packagist.org/downloads/",
645 | "license": [
646 | "MIT"
647 | ],
648 | "authors": [
649 | {
650 | "name": "Taylor Otwell",
651 | "email": "taylor@laravel.com"
652 | }
653 | ],
654 | "description": "The Illuminate Support package.",
655 | "homepage": "https://laravel.com",
656 | "time": "2018-08-29T10:50:44+00:00"
657 | },
658 | {
659 | "name": "nesbot/carbon",
660 | "version": "1.33.0",
661 | "source": {
662 | "type": "git",
663 | "url": "https://github.com/briannesbitt/Carbon.git",
664 | "reference": "55667c1007a99e82030874b1bb14d24d07108413"
665 | },
666 | "dist": {
667 | "type": "zip",
668 | "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/55667c1007a99e82030874b1bb14d24d07108413",
669 | "reference": "55667c1007a99e82030874b1bb14d24d07108413",
670 | "shasum": ""
671 | },
672 | "require": {
673 | "php": ">=5.3.9",
674 | "symfony/translation": "~2.6 || ~3.0 || ~4.0"
675 | },
676 | "require-dev": {
677 | "friendsofphp/php-cs-fixer": "~2",
678 | "phpunit/phpunit": "^4.8.35 || ^5.7"
679 | },
680 | "type": "library",
681 | "extra": {
682 | "laravel": {
683 | "providers": [
684 | "Carbon\\Laravel\\ServiceProvider"
685 | ]
686 | }
687 | },
688 | "autoload": {
689 | "psr-4": {
690 | "": "src/"
691 | }
692 | },
693 | "notification-url": "https://packagist.org/downloads/",
694 | "license": [
695 | "MIT"
696 | ],
697 | "authors": [
698 | {
699 | "name": "Brian Nesbitt",
700 | "email": "brian@nesbot.com",
701 | "homepage": "http://nesbot.com"
702 | }
703 | ],
704 | "description": "A simple API extension for DateTime.",
705 | "homepage": "http://carbon.nesbot.com",
706 | "keywords": [
707 | "date",
708 | "datetime",
709 | "time"
710 | ],
711 | "time": "2018-08-07T08:39:47+00:00"
712 | },
713 | {
714 | "name": "psr/container",
715 | "version": "1.0.0",
716 | "source": {
717 | "type": "git",
718 | "url": "https://github.com/php-fig/container.git",
719 | "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f"
720 | },
721 | "dist": {
722 | "type": "zip",
723 | "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
724 | "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
725 | "shasum": ""
726 | },
727 | "require": {
728 | "php": ">=5.3.0"
729 | },
730 | "type": "library",
731 | "extra": {
732 | "branch-alias": {
733 | "dev-master": "1.0.x-dev"
734 | }
735 | },
736 | "autoload": {
737 | "psr-4": {
738 | "Psr\\Container\\": "src/"
739 | }
740 | },
741 | "notification-url": "https://packagist.org/downloads/",
742 | "license": [
743 | "MIT"
744 | ],
745 | "authors": [
746 | {
747 | "name": "PHP-FIG",
748 | "homepage": "http://www.php-fig.org/"
749 | }
750 | ],
751 | "description": "Common Container Interface (PHP FIG PSR-11)",
752 | "homepage": "https://github.com/php-fig/container",
753 | "keywords": [
754 | "PSR-11",
755 | "container",
756 | "container-interface",
757 | "container-interop",
758 | "psr"
759 | ],
760 | "time": "2017-02-14T16:28:37+00:00"
761 | },
762 | {
763 | "name": "psr/http-message",
764 | "version": "1.0.1",
765 | "source": {
766 | "type": "git",
767 | "url": "https://github.com/php-fig/http-message.git",
768 | "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
769 | },
770 | "dist": {
771 | "type": "zip",
772 | "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
773 | "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
774 | "shasum": ""
775 | },
776 | "require": {
777 | "php": ">=5.3.0"
778 | },
779 | "type": "library",
780 | "extra": {
781 | "branch-alias": {
782 | "dev-master": "1.0.x-dev"
783 | }
784 | },
785 | "autoload": {
786 | "psr-4": {
787 | "Psr\\Http\\Message\\": "src/"
788 | }
789 | },
790 | "notification-url": "https://packagist.org/downloads/",
791 | "license": [
792 | "MIT"
793 | ],
794 | "authors": [
795 | {
796 | "name": "PHP-FIG",
797 | "homepage": "http://www.php-fig.org/"
798 | }
799 | ],
800 | "description": "Common interface for HTTP messages",
801 | "homepage": "https://github.com/php-fig/http-message",
802 | "keywords": [
803 | "http",
804 | "http-message",
805 | "psr",
806 | "psr-7",
807 | "request",
808 | "response"
809 | ],
810 | "time": "2016-08-06T14:39:51+00:00"
811 | },
812 | {
813 | "name": "psr/log",
814 | "version": "1.0.2",
815 | "source": {
816 | "type": "git",
817 | "url": "https://github.com/php-fig/log.git",
818 | "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d"
819 | },
820 | "dist": {
821 | "type": "zip",
822 | "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
823 | "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
824 | "shasum": ""
825 | },
826 | "require": {
827 | "php": ">=5.3.0"
828 | },
829 | "type": "library",
830 | "extra": {
831 | "branch-alias": {
832 | "dev-master": "1.0.x-dev"
833 | }
834 | },
835 | "autoload": {
836 | "psr-4": {
837 | "Psr\\Log\\": "Psr/Log/"
838 | }
839 | },
840 | "notification-url": "https://packagist.org/downloads/",
841 | "license": [
842 | "MIT"
843 | ],
844 | "authors": [
845 | {
846 | "name": "PHP-FIG",
847 | "homepage": "http://www.php-fig.org/"
848 | }
849 | ],
850 | "description": "Common interface for logging libraries",
851 | "homepage": "https://github.com/php-fig/log",
852 | "keywords": [
853 | "log",
854 | "psr",
855 | "psr-3"
856 | ],
857 | "time": "2016-10-10T12:19:37+00:00"
858 | },
859 | {
860 | "name": "psr/simple-cache",
861 | "version": "1.0.1",
862 | "source": {
863 | "type": "git",
864 | "url": "https://github.com/php-fig/simple-cache.git",
865 | "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b"
866 | },
867 | "dist": {
868 | "type": "zip",
869 | "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b",
870 | "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b",
871 | "shasum": ""
872 | },
873 | "require": {
874 | "php": ">=5.3.0"
875 | },
876 | "type": "library",
877 | "extra": {
878 | "branch-alias": {
879 | "dev-master": "1.0.x-dev"
880 | }
881 | },
882 | "autoload": {
883 | "psr-4": {
884 | "Psr\\SimpleCache\\": "src/"
885 | }
886 | },
887 | "notification-url": "https://packagist.org/downloads/",
888 | "license": [
889 | "MIT"
890 | ],
891 | "authors": [
892 | {
893 | "name": "PHP-FIG",
894 | "homepage": "http://www.php-fig.org/"
895 | }
896 | ],
897 | "description": "Common interfaces for simple caching",
898 | "keywords": [
899 | "cache",
900 | "caching",
901 | "psr",
902 | "psr-16",
903 | "simple-cache"
904 | ],
905 | "time": "2017-10-23T01:57:42+00:00"
906 | },
907 | {
908 | "name": "ratchet/rfc6455",
909 | "version": "0.2.4",
910 | "source": {
911 | "type": "git",
912 | "url": "https://github.com/ratchetphp/RFC6455.git",
913 | "reference": "1612f528c3496ad06e910d0f8b6f16ab97696706"
914 | },
915 | "dist": {
916 | "type": "zip",
917 | "url": "https://api.github.com/repos/ratchetphp/RFC6455/zipball/1612f528c3496ad06e910d0f8b6f16ab97696706",
918 | "reference": "1612f528c3496ad06e910d0f8b6f16ab97696706",
919 | "shasum": ""
920 | },
921 | "require": {
922 | "guzzlehttp/psr7": "^1.0",
923 | "php": ">=5.4.2"
924 | },
925 | "require-dev": {
926 | "phpunit/phpunit": "4.8.*",
927 | "react/http": "^0.4.1",
928 | "react/socket-client": "^0.4.3"
929 | },
930 | "type": "library",
931 | "autoload": {
932 | "psr-4": {
933 | "Ratchet\\RFC6455\\": "src"
934 | }
935 | },
936 | "notification-url": "https://packagist.org/downloads/",
937 | "license": [
938 | "MIT"
939 | ],
940 | "authors": [
941 | {
942 | "name": "Chris Boden",
943 | "email": "cboden@gmail.com",
944 | "role": "Developer"
945 | }
946 | ],
947 | "description": "RFC6455 WebSocket protocol handler",
948 | "homepage": "http://socketo.me",
949 | "keywords": [
950 | "WebSockets",
951 | "rfc6455",
952 | "websocket"
953 | ],
954 | "time": "2018-05-02T14:52:00+00:00"
955 | },
956 | {
957 | "name": "react/cache",
958 | "version": "v0.5.0",
959 | "source": {
960 | "type": "git",
961 | "url": "https://github.com/reactphp/cache.git",
962 | "reference": "7d7da7fb7574d471904ba357b39bbf110ccdbf66"
963 | },
964 | "dist": {
965 | "type": "zip",
966 | "url": "https://api.github.com/repos/reactphp/cache/zipball/7d7da7fb7574d471904ba357b39bbf110ccdbf66",
967 | "reference": "7d7da7fb7574d471904ba357b39bbf110ccdbf66",
968 | "shasum": ""
969 | },
970 | "require": {
971 | "php": ">=5.3.0",
972 | "react/promise": "~2.0|~1.1"
973 | },
974 | "require-dev": {
975 | "phpunit/phpunit": "^6.4 || ^5.7 || ^4.8.35"
976 | },
977 | "type": "library",
978 | "autoload": {
979 | "psr-4": {
980 | "React\\Cache\\": "src/"
981 | }
982 | },
983 | "notification-url": "https://packagist.org/downloads/",
984 | "license": [
985 | "MIT"
986 | ],
987 | "description": "Async, Promise-based cache interface for ReactPHP",
988 | "keywords": [
989 | "cache",
990 | "caching",
991 | "promise",
992 | "reactphp"
993 | ],
994 | "time": "2018-06-25T12:52:40+00:00"
995 | },
996 | {
997 | "name": "react/dns",
998 | "version": "v0.4.15",
999 | "source": {
1000 | "type": "git",
1001 | "url": "https://github.com/reactphp/dns.git",
1002 | "reference": "319e110a436d26a2fa137cfa3ef2063951715794"
1003 | },
1004 | "dist": {
1005 | "type": "zip",
1006 | "url": "https://api.github.com/repos/reactphp/dns/zipball/319e110a436d26a2fa137cfa3ef2063951715794",
1007 | "reference": "319e110a436d26a2fa137cfa3ef2063951715794",
1008 | "shasum": ""
1009 | },
1010 | "require": {
1011 | "php": ">=5.3.0",
1012 | "react/cache": "^0.5 || ^0.4 || ^0.3",
1013 | "react/event-loop": "^1.0 || ^0.5 || ^0.4 || ^0.3.5",
1014 | "react/promise": "^2.1 || ^1.2.1",
1015 | "react/promise-timer": "^1.2",
1016 | "react/stream": "^1.0 || ^0.7 || ^0.6 || ^0.5 || ^0.4.5"
1017 | },
1018 | "require-dev": {
1019 | "clue/block-react": "^1.2",
1020 | "phpunit/phpunit": "^6.4 || ^5.7 || ^4.8.35"
1021 | },
1022 | "type": "library",
1023 | "autoload": {
1024 | "psr-4": {
1025 | "React\\Dns\\": "src"
1026 | }
1027 | },
1028 | "notification-url": "https://packagist.org/downloads/",
1029 | "license": [
1030 | "MIT"
1031 | ],
1032 | "description": "Async DNS resolver for ReactPHP",
1033 | "keywords": [
1034 | "async",
1035 | "dns",
1036 | "dns-resolver",
1037 | "reactphp"
1038 | ],
1039 | "time": "2018-07-02T12:17:56+00:00"
1040 | },
1041 | {
1042 | "name": "react/event-loop",
1043 | "version": "v0.4.3",
1044 | "source": {
1045 | "type": "git",
1046 | "url": "https://github.com/reactphp/event-loop.git",
1047 | "reference": "8bde03488ee897dc6bb3d91e4e17c353f9c5252f"
1048 | },
1049 | "dist": {
1050 | "type": "zip",
1051 | "url": "https://api.github.com/repos/reactphp/event-loop/zipball/8bde03488ee897dc6bb3d91e4e17c353f9c5252f",
1052 | "reference": "8bde03488ee897dc6bb3d91e4e17c353f9c5252f",
1053 | "shasum": ""
1054 | },
1055 | "require": {
1056 | "php": ">=5.4.0"
1057 | },
1058 | "require-dev": {
1059 | "phpunit/phpunit": "~4.8"
1060 | },
1061 | "suggest": {
1062 | "ext-event": "~1.0",
1063 | "ext-libev": "*",
1064 | "ext-libevent": ">=0.1.0"
1065 | },
1066 | "type": "library",
1067 | "autoload": {
1068 | "psr-4": {
1069 | "React\\EventLoop\\": "src"
1070 | }
1071 | },
1072 | "notification-url": "https://packagist.org/downloads/",
1073 | "license": [
1074 | "MIT"
1075 | ],
1076 | "description": "Event loop abstraction layer that libraries can use for evented I/O.",
1077 | "keywords": [
1078 | "asynchronous",
1079 | "event-loop"
1080 | ],
1081 | "time": "2017-04-27T10:56:23+00:00"
1082 | },
1083 | {
1084 | "name": "react/promise",
1085 | "version": "v2.7.0",
1086 | "source": {
1087 | "type": "git",
1088 | "url": "https://github.com/reactphp/promise.git",
1089 | "reference": "f4edc2581617431aea50430749db55cc3fc031b3"
1090 | },
1091 | "dist": {
1092 | "type": "zip",
1093 | "url": "https://api.github.com/repos/reactphp/promise/zipball/f4edc2581617431aea50430749db55cc3fc031b3",
1094 | "reference": "f4edc2581617431aea50430749db55cc3fc031b3",
1095 | "shasum": ""
1096 | },
1097 | "require": {
1098 | "php": ">=5.4.0"
1099 | },
1100 | "require-dev": {
1101 | "phpunit/phpunit": "~4.8"
1102 | },
1103 | "type": "library",
1104 | "autoload": {
1105 | "psr-4": {
1106 | "React\\Promise\\": "src/"
1107 | },
1108 | "files": [
1109 | "src/functions_include.php"
1110 | ]
1111 | },
1112 | "notification-url": "https://packagist.org/downloads/",
1113 | "license": [
1114 | "MIT"
1115 | ],
1116 | "authors": [
1117 | {
1118 | "name": "Jan Sorgalla",
1119 | "email": "jsorgalla@gmail.com"
1120 | }
1121 | ],
1122 | "description": "A lightweight implementation of CommonJS Promises/A for PHP",
1123 | "keywords": [
1124 | "promise",
1125 | "promises"
1126 | ],
1127 | "time": "2018-06-13T15:59:06+00:00"
1128 | },
1129 | {
1130 | "name": "react/promise-timer",
1131 | "version": "v1.5.0",
1132 | "source": {
1133 | "type": "git",
1134 | "url": "https://github.com/reactphp/promise-timer.git",
1135 | "reference": "a11206938ca2394dc7bb368f5da25cd4533fa603"
1136 | },
1137 | "dist": {
1138 | "type": "zip",
1139 | "url": "https://api.github.com/repos/reactphp/promise-timer/zipball/a11206938ca2394dc7bb368f5da25cd4533fa603",
1140 | "reference": "a11206938ca2394dc7bb368f5da25cd4533fa603",
1141 | "shasum": ""
1142 | },
1143 | "require": {
1144 | "php": ">=5.3",
1145 | "react/event-loop": "^1.0 || ^0.5 || ^0.4 || ^0.3.5",
1146 | "react/promise": "^2.7.0 || ^1.2.1"
1147 | },
1148 | "require-dev": {
1149 | "phpunit/phpunit": "^6.4 || ^5.7 || ^4.8.35"
1150 | },
1151 | "type": "library",
1152 | "autoload": {
1153 | "psr-4": {
1154 | "React\\Promise\\Timer\\": "src/"
1155 | },
1156 | "files": [
1157 | "src/functions.php"
1158 | ]
1159 | },
1160 | "notification-url": "https://packagist.org/downloads/",
1161 | "license": [
1162 | "MIT"
1163 | ],
1164 | "authors": [
1165 | {
1166 | "name": "Christian Lück",
1167 | "email": "christian@lueck.tv"
1168 | }
1169 | ],
1170 | "description": "A trivial implementation of timeouts for Promises, built on top of ReactPHP.",
1171 | "homepage": "https://github.com/reactphp/promise-timer",
1172 | "keywords": [
1173 | "async",
1174 | "event-loop",
1175 | "promise",
1176 | "reactphp",
1177 | "timeout",
1178 | "timer"
1179 | ],
1180 | "time": "2018-06-13T16:45:37+00:00"
1181 | },
1182 | {
1183 | "name": "react/socket",
1184 | "version": "v1.0.0",
1185 | "source": {
1186 | "type": "git",
1187 | "url": "https://github.com/reactphp/socket.git",
1188 | "reference": "476e2644a634c6301b8111e6d22a61679e6e6bd0"
1189 | },
1190 | "dist": {
1191 | "type": "zip",
1192 | "url": "https://api.github.com/repos/reactphp/socket/zipball/476e2644a634c6301b8111e6d22a61679e6e6bd0",
1193 | "reference": "476e2644a634c6301b8111e6d22a61679e6e6bd0",
1194 | "shasum": ""
1195 | },
1196 | "require": {
1197 | "evenement/evenement": "^3.0 || ^2.0 || ^1.0",
1198 | "php": ">=5.3.0",
1199 | "react/dns": "^0.4.13",
1200 | "react/event-loop": "^1.0 || ^0.5 || ^0.4 || ^0.3.5",
1201 | "react/promise": "^2.6.0 || ^1.2.1",
1202 | "react/promise-timer": "^1.4.0",
1203 | "react/stream": "^1.0 || ^0.7.1"
1204 | },
1205 | "require-dev": {
1206 | "clue/block-react": "^1.2",
1207 | "phpunit/phpunit": "^6.4 || ^5.7 || ^4.8.35"
1208 | },
1209 | "type": "library",
1210 | "autoload": {
1211 | "psr-4": {
1212 | "React\\Socket\\": "src"
1213 | }
1214 | },
1215 | "notification-url": "https://packagist.org/downloads/",
1216 | "license": [
1217 | "MIT"
1218 | ],
1219 | "description": "Async, streaming plaintext TCP/IP and secure TLS socket server and client connections for ReactPHP",
1220 | "keywords": [
1221 | "Connection",
1222 | "Socket",
1223 | "async",
1224 | "reactphp",
1225 | "stream"
1226 | ],
1227 | "time": "2018-07-11T14:38:22+00:00"
1228 | },
1229 | {
1230 | "name": "react/stream",
1231 | "version": "v1.0.0",
1232 | "source": {
1233 | "type": "git",
1234 | "url": "https://github.com/reactphp/stream.git",
1235 | "reference": "fdd0140f42805d65bf9687636503db0b326d2244"
1236 | },
1237 | "dist": {
1238 | "type": "zip",
1239 | "url": "https://api.github.com/repos/reactphp/stream/zipball/fdd0140f42805d65bf9687636503db0b326d2244",
1240 | "reference": "fdd0140f42805d65bf9687636503db0b326d2244",
1241 | "shasum": ""
1242 | },
1243 | "require": {
1244 | "evenement/evenement": "^3.0 || ^2.0 || ^1.0",
1245 | "php": ">=5.3.8",
1246 | "react/event-loop": "^1.0 || ^0.5 || ^0.4 || ^0.3.5"
1247 | },
1248 | "require-dev": {
1249 | "clue/stream-filter": "~1.2",
1250 | "phpunit/phpunit": "^6.4 || ^5.7 || ^4.8.35"
1251 | },
1252 | "type": "library",
1253 | "autoload": {
1254 | "psr-4": {
1255 | "React\\Stream\\": "src"
1256 | }
1257 | },
1258 | "notification-url": "https://packagist.org/downloads/",
1259 | "license": [
1260 | "MIT"
1261 | ],
1262 | "description": "Event-driven readable and writable streams for non-blocking I/O in ReactPHP",
1263 | "keywords": [
1264 | "event-driven",
1265 | "io",
1266 | "non-blocking",
1267 | "pipe",
1268 | "reactphp",
1269 | "readable",
1270 | "stream",
1271 | "writable"
1272 | ],
1273 | "time": "2018-07-11T14:38:16+00:00"
1274 | },
1275 | {
1276 | "name": "react/zmq",
1277 | "version": "v0.3.0",
1278 | "source": {
1279 | "type": "git",
1280 | "url": "https://github.com/reactphp/zmq.git",
1281 | "reference": "2865e3b23000751ed443d3f108da2735abf80716"
1282 | },
1283 | "dist": {
1284 | "type": "zip",
1285 | "url": "https://api.github.com/repos/reactphp/zmq/zipball/2865e3b23000751ed443d3f108da2735abf80716",
1286 | "reference": "2865e3b23000751ed443d3f108da2735abf80716",
1287 | "shasum": ""
1288 | },
1289 | "require": {
1290 | "evenement/evenement": "~2.0",
1291 | "ext-zmq": "*",
1292 | "php": ">=5.4.0",
1293 | "react/event-loop": "0.4.*"
1294 | },
1295 | "require-dev": {
1296 | "ext-pcntl": "*"
1297 | },
1298 | "type": "library",
1299 | "extra": {
1300 | "branch-alias": {
1301 | "dev-master": "0.4-dev"
1302 | }
1303 | },
1304 | "autoload": {
1305 | "psr-0": {
1306 | "React\\ZMQ": "src"
1307 | }
1308 | },
1309 | "notification-url": "https://packagist.org/downloads/",
1310 | "license": [
1311 | "MIT"
1312 | ],
1313 | "description": "ZeroMQ bindings for React.",
1314 | "keywords": [
1315 | "zeromq",
1316 | "zmq"
1317 | ],
1318 | "time": "2014-05-25T17:54:51+00:00"
1319 | },
1320 | {
1321 | "name": "symfony/console",
1322 | "version": "v4.1.4",
1323 | "source": {
1324 | "type": "git",
1325 | "url": "https://github.com/symfony/console.git",
1326 | "reference": "ca80b8ced97cf07390078b29773dc384c39eee1f"
1327 | },
1328 | "dist": {
1329 | "type": "zip",
1330 | "url": "https://api.github.com/repos/symfony/console/zipball/ca80b8ced97cf07390078b29773dc384c39eee1f",
1331 | "reference": "ca80b8ced97cf07390078b29773dc384c39eee1f",
1332 | "shasum": ""
1333 | },
1334 | "require": {
1335 | "php": "^7.1.3",
1336 | "symfony/polyfill-mbstring": "~1.0"
1337 | },
1338 | "conflict": {
1339 | "symfony/dependency-injection": "<3.4",
1340 | "symfony/process": "<3.3"
1341 | },
1342 | "require-dev": {
1343 | "psr/log": "~1.0",
1344 | "symfony/config": "~3.4|~4.0",
1345 | "symfony/dependency-injection": "~3.4|~4.0",
1346 | "symfony/event-dispatcher": "~3.4|~4.0",
1347 | "symfony/lock": "~3.4|~4.0",
1348 | "symfony/process": "~3.4|~4.0"
1349 | },
1350 | "suggest": {
1351 | "psr/log-implementation": "For using the console logger",
1352 | "symfony/event-dispatcher": "",
1353 | "symfony/lock": "",
1354 | "symfony/process": ""
1355 | },
1356 | "type": "library",
1357 | "extra": {
1358 | "branch-alias": {
1359 | "dev-master": "4.1-dev"
1360 | }
1361 | },
1362 | "autoload": {
1363 | "psr-4": {
1364 | "Symfony\\Component\\Console\\": ""
1365 | },
1366 | "exclude-from-classmap": [
1367 | "/Tests/"
1368 | ]
1369 | },
1370 | "notification-url": "https://packagist.org/downloads/",
1371 | "license": [
1372 | "MIT"
1373 | ],
1374 | "authors": [
1375 | {
1376 | "name": "Fabien Potencier",
1377 | "email": "fabien@symfony.com"
1378 | },
1379 | {
1380 | "name": "Symfony Community",
1381 | "homepage": "https://symfony.com/contributors"
1382 | }
1383 | ],
1384 | "description": "Symfony Console Component",
1385 | "homepage": "https://symfony.com",
1386 | "time": "2018-07-26T11:24:31+00:00"
1387 | },
1388 | {
1389 | "name": "symfony/debug",
1390 | "version": "v4.1.4",
1391 | "source": {
1392 | "type": "git",
1393 | "url": "https://github.com/symfony/debug.git",
1394 | "reference": "47ead688f1f2877f3f14219670f52e4722ee7052"
1395 | },
1396 | "dist": {
1397 | "type": "zip",
1398 | "url": "https://api.github.com/repos/symfony/debug/zipball/47ead688f1f2877f3f14219670f52e4722ee7052",
1399 | "reference": "47ead688f1f2877f3f14219670f52e4722ee7052",
1400 | "shasum": ""
1401 | },
1402 | "require": {
1403 | "php": "^7.1.3",
1404 | "psr/log": "~1.0"
1405 | },
1406 | "conflict": {
1407 | "symfony/http-kernel": "<3.4"
1408 | },
1409 | "require-dev": {
1410 | "symfony/http-kernel": "~3.4|~4.0"
1411 | },
1412 | "type": "library",
1413 | "extra": {
1414 | "branch-alias": {
1415 | "dev-master": "4.1-dev"
1416 | }
1417 | },
1418 | "autoload": {
1419 | "psr-4": {
1420 | "Symfony\\Component\\Debug\\": ""
1421 | },
1422 | "exclude-from-classmap": [
1423 | "/Tests/"
1424 | ]
1425 | },
1426 | "notification-url": "https://packagist.org/downloads/",
1427 | "license": [
1428 | "MIT"
1429 | ],
1430 | "authors": [
1431 | {
1432 | "name": "Fabien Potencier",
1433 | "email": "fabien@symfony.com"
1434 | },
1435 | {
1436 | "name": "Symfony Community",
1437 | "homepage": "https://symfony.com/contributors"
1438 | }
1439 | ],
1440 | "description": "Symfony Debug Component",
1441 | "homepage": "https://symfony.com",
1442 | "time": "2018-08-03T11:13:38+00:00"
1443 | },
1444 | {
1445 | "name": "symfony/event-dispatcher",
1446 | "version": "v4.1.4",
1447 | "source": {
1448 | "type": "git",
1449 | "url": "https://github.com/symfony/event-dispatcher.git",
1450 | "reference": "bfb30c2ad377615a463ebbc875eba64a99f6aa3e"
1451 | },
1452 | "dist": {
1453 | "type": "zip",
1454 | "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/bfb30c2ad377615a463ebbc875eba64a99f6aa3e",
1455 | "reference": "bfb30c2ad377615a463ebbc875eba64a99f6aa3e",
1456 | "shasum": ""
1457 | },
1458 | "require": {
1459 | "php": "^7.1.3"
1460 | },
1461 | "conflict": {
1462 | "symfony/dependency-injection": "<3.4"
1463 | },
1464 | "require-dev": {
1465 | "psr/log": "~1.0",
1466 | "symfony/config": "~3.4|~4.0",
1467 | "symfony/dependency-injection": "~3.4|~4.0",
1468 | "symfony/expression-language": "~3.4|~4.0",
1469 | "symfony/stopwatch": "~3.4|~4.0"
1470 | },
1471 | "suggest": {
1472 | "symfony/dependency-injection": "",
1473 | "symfony/http-kernel": ""
1474 | },
1475 | "type": "library",
1476 | "extra": {
1477 | "branch-alias": {
1478 | "dev-master": "4.1-dev"
1479 | }
1480 | },
1481 | "autoload": {
1482 | "psr-4": {
1483 | "Symfony\\Component\\EventDispatcher\\": ""
1484 | },
1485 | "exclude-from-classmap": [
1486 | "/Tests/"
1487 | ]
1488 | },
1489 | "notification-url": "https://packagist.org/downloads/",
1490 | "license": [
1491 | "MIT"
1492 | ],
1493 | "authors": [
1494 | {
1495 | "name": "Fabien Potencier",
1496 | "email": "fabien@symfony.com"
1497 | },
1498 | {
1499 | "name": "Symfony Community",
1500 | "homepage": "https://symfony.com/contributors"
1501 | }
1502 | ],
1503 | "description": "Symfony EventDispatcher Component",
1504 | "homepage": "https://symfony.com",
1505 | "time": "2018-07-26T09:10:45+00:00"
1506 | },
1507 | {
1508 | "name": "symfony/finder",
1509 | "version": "v4.1.4",
1510 | "source": {
1511 | "type": "git",
1512 | "url": "https://github.com/symfony/finder.git",
1513 | "reference": "e162f1df3102d0b7472805a5a9d5db9fcf0a8068"
1514 | },
1515 | "dist": {
1516 | "type": "zip",
1517 | "url": "https://api.github.com/repos/symfony/finder/zipball/e162f1df3102d0b7472805a5a9d5db9fcf0a8068",
1518 | "reference": "e162f1df3102d0b7472805a5a9d5db9fcf0a8068",
1519 | "shasum": ""
1520 | },
1521 | "require": {
1522 | "php": "^7.1.3"
1523 | },
1524 | "type": "library",
1525 | "extra": {
1526 | "branch-alias": {
1527 | "dev-master": "4.1-dev"
1528 | }
1529 | },
1530 | "autoload": {
1531 | "psr-4": {
1532 | "Symfony\\Component\\Finder\\": ""
1533 | },
1534 | "exclude-from-classmap": [
1535 | "/Tests/"
1536 | ]
1537 | },
1538 | "notification-url": "https://packagist.org/downloads/",
1539 | "license": [
1540 | "MIT"
1541 | ],
1542 | "authors": [
1543 | {
1544 | "name": "Fabien Potencier",
1545 | "email": "fabien@symfony.com"
1546 | },
1547 | {
1548 | "name": "Symfony Community",
1549 | "homepage": "https://symfony.com/contributors"
1550 | }
1551 | ],
1552 | "description": "Symfony Finder Component",
1553 | "homepage": "https://symfony.com",
1554 | "time": "2018-07-26T11:24:31+00:00"
1555 | },
1556 | {
1557 | "name": "symfony/http-foundation",
1558 | "version": "v4.1.4",
1559 | "source": {
1560 | "type": "git",
1561 | "url": "https://github.com/symfony/http-foundation.git",
1562 | "reference": "3a5c91e133b220bb882b3cd773ba91bf39989345"
1563 | },
1564 | "dist": {
1565 | "type": "zip",
1566 | "url": "https://api.github.com/repos/symfony/http-foundation/zipball/3a5c91e133b220bb882b3cd773ba91bf39989345",
1567 | "reference": "3a5c91e133b220bb882b3cd773ba91bf39989345",
1568 | "shasum": ""
1569 | },
1570 | "require": {
1571 | "php": "^7.1.3",
1572 | "symfony/polyfill-mbstring": "~1.1"
1573 | },
1574 | "require-dev": {
1575 | "predis/predis": "~1.0",
1576 | "symfony/expression-language": "~3.4|~4.0"
1577 | },
1578 | "type": "library",
1579 | "extra": {
1580 | "branch-alias": {
1581 | "dev-master": "4.1-dev"
1582 | }
1583 | },
1584 | "autoload": {
1585 | "psr-4": {
1586 | "Symfony\\Component\\HttpFoundation\\": ""
1587 | },
1588 | "exclude-from-classmap": [
1589 | "/Tests/"
1590 | ]
1591 | },
1592 | "notification-url": "https://packagist.org/downloads/",
1593 | "license": [
1594 | "MIT"
1595 | ],
1596 | "authors": [
1597 | {
1598 | "name": "Fabien Potencier",
1599 | "email": "fabien@symfony.com"
1600 | },
1601 | {
1602 | "name": "Symfony Community",
1603 | "homepage": "https://symfony.com/contributors"
1604 | }
1605 | ],
1606 | "description": "Symfony HttpFoundation Component",
1607 | "homepage": "https://symfony.com",
1608 | "time": "2018-08-27T17:47:02+00:00"
1609 | },
1610 | {
1611 | "name": "symfony/http-kernel",
1612 | "version": "v4.1.4",
1613 | "source": {
1614 | "type": "git",
1615 | "url": "https://github.com/symfony/http-kernel.git",
1616 | "reference": "33de0a1ff2e1720096189e3ced682d7a4e8f5e35"
1617 | },
1618 | "dist": {
1619 | "type": "zip",
1620 | "url": "https://api.github.com/repos/symfony/http-kernel/zipball/33de0a1ff2e1720096189e3ced682d7a4e8f5e35",
1621 | "reference": "33de0a1ff2e1720096189e3ced682d7a4e8f5e35",
1622 | "shasum": ""
1623 | },
1624 | "require": {
1625 | "php": "^7.1.3",
1626 | "psr/log": "~1.0",
1627 | "symfony/debug": "~3.4|~4.0",
1628 | "symfony/event-dispatcher": "~4.1",
1629 | "symfony/http-foundation": "^4.1.1",
1630 | "symfony/polyfill-ctype": "~1.8"
1631 | },
1632 | "conflict": {
1633 | "symfony/config": "<3.4",
1634 | "symfony/dependency-injection": "<4.1",
1635 | "symfony/var-dumper": "<4.1.1",
1636 | "twig/twig": "<1.34|<2.4,>=2"
1637 | },
1638 | "provide": {
1639 | "psr/log-implementation": "1.0"
1640 | },
1641 | "require-dev": {
1642 | "psr/cache": "~1.0",
1643 | "symfony/browser-kit": "~3.4|~4.0",
1644 | "symfony/config": "~3.4|~4.0",
1645 | "symfony/console": "~3.4|~4.0",
1646 | "symfony/css-selector": "~3.4|~4.0",
1647 | "symfony/dependency-injection": "^4.1",
1648 | "symfony/dom-crawler": "~3.4|~4.0",
1649 | "symfony/expression-language": "~3.4|~4.0",
1650 | "symfony/finder": "~3.4|~4.0",
1651 | "symfony/process": "~3.4|~4.0",
1652 | "symfony/routing": "~3.4|~4.0",
1653 | "symfony/stopwatch": "~3.4|~4.0",
1654 | "symfony/templating": "~3.4|~4.0",
1655 | "symfony/translation": "~3.4|~4.0",
1656 | "symfony/var-dumper": "^4.1.1"
1657 | },
1658 | "suggest": {
1659 | "symfony/browser-kit": "",
1660 | "symfony/config": "",
1661 | "symfony/console": "",
1662 | "symfony/dependency-injection": "",
1663 | "symfony/var-dumper": ""
1664 | },
1665 | "type": "library",
1666 | "extra": {
1667 | "branch-alias": {
1668 | "dev-master": "4.1-dev"
1669 | }
1670 | },
1671 | "autoload": {
1672 | "psr-4": {
1673 | "Symfony\\Component\\HttpKernel\\": ""
1674 | },
1675 | "exclude-from-classmap": [
1676 | "/Tests/"
1677 | ]
1678 | },
1679 | "notification-url": "https://packagist.org/downloads/",
1680 | "license": [
1681 | "MIT"
1682 | ],
1683 | "authors": [
1684 | {
1685 | "name": "Fabien Potencier",
1686 | "email": "fabien@symfony.com"
1687 | },
1688 | {
1689 | "name": "Symfony Community",
1690 | "homepage": "https://symfony.com/contributors"
1691 | }
1692 | ],
1693 | "description": "Symfony HttpKernel Component",
1694 | "homepage": "https://symfony.com",
1695 | "time": "2018-08-28T06:17:42+00:00"
1696 | },
1697 | {
1698 | "name": "symfony/polyfill-ctype",
1699 | "version": "v1.9.0",
1700 | "source": {
1701 | "type": "git",
1702 | "url": "https://github.com/symfony/polyfill-ctype.git",
1703 | "reference": "e3d826245268269cd66f8326bd8bc066687b4a19"
1704 | },
1705 | "dist": {
1706 | "type": "zip",
1707 | "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/e3d826245268269cd66f8326bd8bc066687b4a19",
1708 | "reference": "e3d826245268269cd66f8326bd8bc066687b4a19",
1709 | "shasum": ""
1710 | },
1711 | "require": {
1712 | "php": ">=5.3.3"
1713 | },
1714 | "suggest": {
1715 | "ext-ctype": "For best performance"
1716 | },
1717 | "type": "library",
1718 | "extra": {
1719 | "branch-alias": {
1720 | "dev-master": "1.9-dev"
1721 | }
1722 | },
1723 | "autoload": {
1724 | "psr-4": {
1725 | "Symfony\\Polyfill\\Ctype\\": ""
1726 | },
1727 | "files": [
1728 | "bootstrap.php"
1729 | ]
1730 | },
1731 | "notification-url": "https://packagist.org/downloads/",
1732 | "license": [
1733 | "MIT"
1734 | ],
1735 | "authors": [
1736 | {
1737 | "name": "Symfony Community",
1738 | "homepage": "https://symfony.com/contributors"
1739 | },
1740 | {
1741 | "name": "Gert de Pagter",
1742 | "email": "BackEndTea@gmail.com"
1743 | }
1744 | ],
1745 | "description": "Symfony polyfill for ctype functions",
1746 | "homepage": "https://symfony.com",
1747 | "keywords": [
1748 | "compatibility",
1749 | "ctype",
1750 | "polyfill",
1751 | "portable"
1752 | ],
1753 | "time": "2018-08-06T14:22:27+00:00"
1754 | },
1755 | {
1756 | "name": "symfony/polyfill-mbstring",
1757 | "version": "v1.9.0",
1758 | "source": {
1759 | "type": "git",
1760 | "url": "https://github.com/symfony/polyfill-mbstring.git",
1761 | "reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8"
1762 | },
1763 | "dist": {
1764 | "type": "zip",
1765 | "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/d0cd638f4634c16d8df4508e847f14e9e43168b8",
1766 | "reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8",
1767 | "shasum": ""
1768 | },
1769 | "require": {
1770 | "php": ">=5.3.3"
1771 | },
1772 | "suggest": {
1773 | "ext-mbstring": "For best performance"
1774 | },
1775 | "type": "library",
1776 | "extra": {
1777 | "branch-alias": {
1778 | "dev-master": "1.9-dev"
1779 | }
1780 | },
1781 | "autoload": {
1782 | "psr-4": {
1783 | "Symfony\\Polyfill\\Mbstring\\": ""
1784 | },
1785 | "files": [
1786 | "bootstrap.php"
1787 | ]
1788 | },
1789 | "notification-url": "https://packagist.org/downloads/",
1790 | "license": [
1791 | "MIT"
1792 | ],
1793 | "authors": [
1794 | {
1795 | "name": "Nicolas Grekas",
1796 | "email": "p@tchwork.com"
1797 | },
1798 | {
1799 | "name": "Symfony Community",
1800 | "homepage": "https://symfony.com/contributors"
1801 | }
1802 | ],
1803 | "description": "Symfony polyfill for the Mbstring extension",
1804 | "homepage": "https://symfony.com",
1805 | "keywords": [
1806 | "compatibility",
1807 | "mbstring",
1808 | "polyfill",
1809 | "portable",
1810 | "shim"
1811 | ],
1812 | "time": "2018-08-06T14:22:27+00:00"
1813 | },
1814 | {
1815 | "name": "symfony/routing",
1816 | "version": "v4.1.4",
1817 | "source": {
1818 | "type": "git",
1819 | "url": "https://github.com/symfony/routing.git",
1820 | "reference": "a5784c2ec4168018c87b38f0e4f39d2278499f51"
1821 | },
1822 | "dist": {
1823 | "type": "zip",
1824 | "url": "https://api.github.com/repos/symfony/routing/zipball/a5784c2ec4168018c87b38f0e4f39d2278499f51",
1825 | "reference": "a5784c2ec4168018c87b38f0e4f39d2278499f51",
1826 | "shasum": ""
1827 | },
1828 | "require": {
1829 | "php": "^7.1.3"
1830 | },
1831 | "conflict": {
1832 | "symfony/config": "<3.4",
1833 | "symfony/dependency-injection": "<3.4",
1834 | "symfony/yaml": "<3.4"
1835 | },
1836 | "require-dev": {
1837 | "doctrine/annotations": "~1.0",
1838 | "psr/log": "~1.0",
1839 | "symfony/config": "~3.4|~4.0",
1840 | "symfony/dependency-injection": "~3.4|~4.0",
1841 | "symfony/expression-language": "~3.4|~4.0",
1842 | "symfony/http-foundation": "~3.4|~4.0",
1843 | "symfony/yaml": "~3.4|~4.0"
1844 | },
1845 | "suggest": {
1846 | "doctrine/annotations": "For using the annotation loader",
1847 | "symfony/config": "For using the all-in-one router or any loader",
1848 | "symfony/dependency-injection": "For loading routes from a service",
1849 | "symfony/expression-language": "For using expression matching",
1850 | "symfony/http-foundation": "For using a Symfony Request object",
1851 | "symfony/yaml": "For using the YAML loader"
1852 | },
1853 | "type": "library",
1854 | "extra": {
1855 | "branch-alias": {
1856 | "dev-master": "4.1-dev"
1857 | }
1858 | },
1859 | "autoload": {
1860 | "psr-4": {
1861 | "Symfony\\Component\\Routing\\": ""
1862 | },
1863 | "exclude-from-classmap": [
1864 | "/Tests/"
1865 | ]
1866 | },
1867 | "notification-url": "https://packagist.org/downloads/",
1868 | "license": [
1869 | "MIT"
1870 | ],
1871 | "authors": [
1872 | {
1873 | "name": "Fabien Potencier",
1874 | "email": "fabien@symfony.com"
1875 | },
1876 | {
1877 | "name": "Symfony Community",
1878 | "homepage": "https://symfony.com/contributors"
1879 | }
1880 | ],
1881 | "description": "Symfony Routing Component",
1882 | "homepage": "https://symfony.com",
1883 | "keywords": [
1884 | "router",
1885 | "routing",
1886 | "uri",
1887 | "url"
1888 | ],
1889 | "time": "2018-08-03T07:58:40+00:00"
1890 | },
1891 | {
1892 | "name": "symfony/translation",
1893 | "version": "v4.1.4",
1894 | "source": {
1895 | "type": "git",
1896 | "url": "https://github.com/symfony/translation.git",
1897 | "reference": "fa2182669f7983b7aa5f1a770d053f79f0ef144f"
1898 | },
1899 | "dist": {
1900 | "type": "zip",
1901 | "url": "https://api.github.com/repos/symfony/translation/zipball/fa2182669f7983b7aa5f1a770d053f79f0ef144f",
1902 | "reference": "fa2182669f7983b7aa5f1a770d053f79f0ef144f",
1903 | "shasum": ""
1904 | },
1905 | "require": {
1906 | "php": "^7.1.3",
1907 | "symfony/polyfill-mbstring": "~1.0"
1908 | },
1909 | "conflict": {
1910 | "symfony/config": "<3.4",
1911 | "symfony/dependency-injection": "<3.4",
1912 | "symfony/yaml": "<3.4"
1913 | },
1914 | "require-dev": {
1915 | "psr/log": "~1.0",
1916 | "symfony/config": "~3.4|~4.0",
1917 | "symfony/console": "~3.4|~4.0",
1918 | "symfony/dependency-injection": "~3.4|~4.0",
1919 | "symfony/finder": "~2.8|~3.0|~4.0",
1920 | "symfony/intl": "~3.4|~4.0",
1921 | "symfony/yaml": "~3.4|~4.0"
1922 | },
1923 | "suggest": {
1924 | "psr/log-implementation": "To use logging capability in translator",
1925 | "symfony/config": "",
1926 | "symfony/yaml": ""
1927 | },
1928 | "type": "library",
1929 | "extra": {
1930 | "branch-alias": {
1931 | "dev-master": "4.1-dev"
1932 | }
1933 | },
1934 | "autoload": {
1935 | "psr-4": {
1936 | "Symfony\\Component\\Translation\\": ""
1937 | },
1938 | "exclude-from-classmap": [
1939 | "/Tests/"
1940 | ]
1941 | },
1942 | "notification-url": "https://packagist.org/downloads/",
1943 | "license": [
1944 | "MIT"
1945 | ],
1946 | "authors": [
1947 | {
1948 | "name": "Fabien Potencier",
1949 | "email": "fabien@symfony.com"
1950 | },
1951 | {
1952 | "name": "Symfony Community",
1953 | "homepage": "https://symfony.com/contributors"
1954 | }
1955 | ],
1956 | "description": "Symfony Translation Component",
1957 | "homepage": "https://symfony.com",
1958 | "time": "2018-08-07T12:45:11+00:00"
1959 | }
1960 | ],
1961 | "packages-dev": [],
1962 | "aliases": [],
1963 | "minimum-stability": "stable",
1964 | "stability-flags": [],
1965 | "prefer-stable": false,
1966 | "prefer-lowest": false,
1967 | "platform": {
1968 | "php": ">=7.1.0",
1969 | "ext-zmq": "*"
1970 | },
1971 | "platform-dev": []
1972 | }
1973 |
--------------------------------------------------------------------------------
/src/Console/Commands/RatchetServerCommand.php:
--------------------------------------------------------------------------------
1 | class
94 | */
95 | protected $ratchetServer;
96 |
97 | /**
98 | * WebSocket server instance.
99 | */
100 | protected $wsServerInstance;
101 |
102 | /**
103 | * Get the console command options.
104 | *
105 | * @return array
106 | */
107 | protected function getOptions()
108 | {
109 | return [
110 | ['host', null, InputOption::VALUE_OPTIONAL, 'Ratchet server host', config('ratchet.host', '0.0.0.0')],
111 | ['port', 'p', InputOption::VALUE_OPTIONAL, 'Ratchet server port', config('ratchet.port', 8080)],
112 | ['class', null, InputOption::VALUE_OPTIONAL, 'Class that implements MessageComponentInterface.', config('ratchet.class')],
113 | ['driver', null, InputOption::VALUE_OPTIONAL, 'Ratchet connection driver [IoServer|WsServer|WampServer]', 'WampServer'],
114 | ['zmq', 'z', null, 'Bind server to a ZeroMQ socket (always on for WampServer)'],
115 | ['keepAlive', null, InputOption::VALUE_OPTIONAL, 'Option to enable WebSocket server keep alive [interval in seconds]', config('ratchet.keepAlive', 0)],
116 | ];
117 | }
118 |
119 | /**
120 | * Execute the console command.
121 | */
122 | public function handle()
123 | {
124 | $this->host = $this->option('host');
125 |
126 | $this->port = intval($this->option('port'));
127 |
128 | $this->class = $this->option('class');
129 |
130 | $this->driver = $this->option('driver');
131 |
132 | $this->keepAlive = $this->option('keepAlive');
133 |
134 | $this->tls = config('ratchet.tls', []);
135 | $peer_name = env('APP_URL');
136 | $pos = strpos($peer_name, '://');
137 | if ($pos !== false) {
138 | $peer_name = substr($peer_name, $pos+3);
139 | }
140 | $this->tls += [
141 | 'peer_name' => $peer_name
142 | ];
143 |
144 | $this->startServer();
145 | }
146 |
147 | /**
148 | * Start the appropriate server.
149 | *
150 | * @param string $driver
151 | */
152 | private function startServer($driver = null)
153 | {
154 | if (! $driver) {
155 | $driver = $this->driver;
156 | }
157 |
158 | $this->info(sprintf('Starting %s server on: %s:%d', $this->option('driver'), $this->host, $this->port));
159 |
160 | $this->createServerInstance();
161 |
162 | $this->{'start'.$driver}()->run();
163 | }
164 |
165 | /**
166 | * Get/generate the server instance from the class provided.
167 | */
168 | private function createServerInstance()
169 | {
170 | if (! $this->serverInstance instanceof $this->class) {
171 | $class = $this->class;
172 | $this->serverInstance = $this->ratchetServer = new $class($this);
173 | }
174 | }
175 |
176 | /**
177 | * Decorate a server instance with a blacklist instance and block any blacklisted addresses.
178 | */
179 | private function bootWithBlacklist()
180 | {
181 | $this->serverInstance = new IpBlackList($this->serverInstance);
182 |
183 | foreach (config('ratchet.blackList') as $host) {
184 | $this->serverInstance->blockAddress($host);
185 | }
186 | }
187 |
188 | /**
189 | * Decorate the server instance with a WebSocket server.
190 | *
191 | * @param bool $withZmq
192 | * @return IoServer
193 | */
194 | private function bootWebSocketServer($withZmq = false)
195 | {
196 | if ($withZmq || $this->option('zmq')) {
197 | $this->bootZmqConnection();
198 | }
199 |
200 | $this->wsServerInstance = new WsServer($this->serverInstance);
201 |
202 | $this->serverInstance = new HttpServer(
203 | $this->wsServerInstance
204 | );
205 |
206 | if($this->keepAlive > 0){
207 | $this->wsServerInstance->enableKeepAlive($this->getEventLoop(), $this->keepAlive);
208 | }
209 |
210 | return $this->bootIoServer();
211 | }
212 |
213 | /**
214 | * Deploy a WampServer
215 | *
216 | * @return IoServer
217 | */
218 | private function startWampServer()
219 | {
220 | if (! $this->serverInstance instanceof RatchetWampServer) {
221 | throw new \Exception("{$this->class} must be an instance of ".RatchetWampServer::class." to create a Wamp server");
222 | }
223 |
224 | // Decorate the server instance with a WampServer
225 | $this->serverInstance = new WampServer($this->serverInstance);
226 |
227 | return $this->bootWebSocketServer(true);
228 | }
229 |
230 | /**
231 | * Deploy a WsServer.
232 | *
233 | * @return IoServer
234 | */
235 | private function startWsServer()
236 | {
237 | if (! $this->serverInstance instanceof RatchetWsServer) {
238 | throw new \Exception("{$this->class} must be an instance of ".RatchetWsServer::class." to create a WebSocket server");
239 | }
240 |
241 | $this->bootWithBlacklist();
242 |
243 | return $this->bootWebSocketServer();
244 | }
245 |
246 | /**
247 | * Deploy an IoServer only
248 | *
249 | * @return IoServer
250 | */
251 | private function startIoServer()
252 | {
253 | $this->bootWithBlacklist();
254 |
255 | return $this->bootIoServer();
256 | }
257 |
258 | /**
259 | * Create the IoServer instance to encapsulate our server in.
260 | *
261 | * @return IoServer
262 | */
263 | private function bootIoServer()
264 | {
265 | $context = [
266 | 'tls' => $this->tls,
267 | ];
268 | $socket = new SocketServer($this->host.':'.$this->port, $this->getEventLoop(), $context);
269 |
270 | return new IoServer(
271 | $this->serverInstance,
272 | $socket,
273 | $this->getEventLoop()
274 | );
275 | }
276 |
277 | /**
278 | * Boot a ZMQ listener and let the Ratchet server handle its events.
279 | */
280 | private function bootZmqConnection()
281 | {
282 | $this->info(sprintf('Starting ZMQ listener on: %s:%s', config('ratchet.zmq.host'), config('ratchet.zmq.port')));
283 |
284 | $context = new ZMQContext($this->getEventLoop());
285 | $socket = $context->getSocket(config('ratchet.zmq.method', \ZMQ::SOCKET_PULL));
286 | $socket->bind(sprintf('tcp://%s:%d', config('ratchet.zmq.host', '127.0.0.1'), config('ratchet.zmq.port', 5555)));
287 |
288 | $socket->on('messages', function ($messages) {
289 | $this->ratchetServer->onEntry($messages);
290 | });
291 |
292 | $socket->on('message', function ($message) {
293 | $this->ratchetServer->onEntry($message);
294 | });
295 | }
296 |
297 | /**
298 | * Generate and return a React EventLoop object.
299 | *
300 | * @return LoopInterface
301 | */
302 | private function getEventLoop()
303 | {
304 | if (! $this->eventLoop instanceof LoopInterface) {
305 | $this->eventLoop = EventLoop::create();
306 | }
307 |
308 | return $this->eventLoop;
309 | }
310 | }
311 |
--------------------------------------------------------------------------------
/src/Examples/Pusher.php:
--------------------------------------------------------------------------------
1 | sendAll($entry[1]);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/Providers/LaravelRatchetServiceProvider.php:
--------------------------------------------------------------------------------
1 | app->register(ThrottleServiceProvider::class);
19 |
20 | $this->app->singleton('command.ratchet.serve', function () {
21 | return new RatchetServerCommand();
22 | });
23 |
24 | $this->commands('command.ratchet.serve');
25 |
26 | $this->mergeConfigFrom(__DIR__.'/../config/ratchet.php', 'ratchet');
27 | }
28 |
29 | /**
30 | * Register routes, translations, views and publishers.
31 | *
32 | * @return void
33 | */
34 | public function boot()
35 | {
36 | $this->loadTranslationsFrom(__DIR__.'/../lang', 'ratchet');
37 |
38 | $this->publishes([
39 | __DIR__.'/../lang' => resource_path('lang/askedio/ratchet'),
40 | ]);
41 |
42 | $this->publishes([
43 | __DIR__.'/../config/ratchet.php' => config_path('ratchet.php'),
44 | ]);
45 | }
46 |
47 | /**
48 | * Get the services provided by the provider.
49 | *
50 | * @return array
51 | */
52 | public function provides()
53 | {
54 | return ['command.ratchet.serve'];
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/RatchetWampServer.php:
--------------------------------------------------------------------------------
1 | console = $console;
17 | }
18 |
19 | /**
20 | * @param string JSON'ified string we'll receive from ZeroMQ
21 | */
22 | public function onEntry($entry)
23 | {
24 | $entryData = json_decode($entry, true);
25 |
26 | if (!array_key_exists($entryData['category'], $this->subscribedTopics)) {
27 | return;
28 | }
29 |
30 | $topic = $this->subscribedTopics[$entryData['category']];
31 |
32 | $topic->broadcast($entryData);
33 | }
34 |
35 | /**
36 | * A request to subscribe to a topic has been made.
37 | *
38 | * @param \Ratchet\ConnectionInterface $conn
39 | * @param string|Topic $topic The topic to subscribe to
40 | */
41 | public function onSubscribe(ConnectionInterface $conn, $topic)
42 | {
43 | $this->console->info("onSubscribe: {$conn->WAMP->sessionId} topic: $topic {$topic->count()}");
44 |
45 | if (!array_key_exists($topic->getId(), $this->subscribedTopics)) {
46 | $this->subscribedTopics[$topic->getId()] = $topic;
47 | $this->console->info("subscribed to topic $topic");
48 | }
49 | }
50 |
51 | /**
52 | * A request to unsubscribe from a topic has been made.
53 | *
54 | * @param \Ratchet\ConnectionInterface $conn
55 | * @param string|Topic $topic The topic to unsubscribe from
56 | */
57 | public function onUnSubscribe(ConnectionInterface $conn, $topic)
58 | {
59 | $this->console->info("onUnSubscribe: topic: $topic {$topic->count()}");
60 | }
61 |
62 | /**
63 | * When a new connection is opened it will be passed to this method.
64 | *
65 | * @param ConnectionInterface $conn The socket/connection that just connected to your application
66 | *
67 | * @throws \Exception
68 | */
69 | public function onOpen(ConnectionInterface $conn)
70 | {
71 | $this->console->info("onOpen ({$conn->WAMP->sessionId})");
72 | }
73 |
74 | /**
75 | * 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.
76 | *
77 | * @param ConnectionInterface $conn The socket/connection that is closing/closed
78 | *
79 | * @throws \Exception
80 | */
81 | public function onClose(ConnectionInterface $conn)
82 | {
83 | $this->console->info("onClose ({$conn->WAMP->sessionId})");
84 | }
85 |
86 | /**
87 | * An RPC call has been received.
88 | *
89 | * @param \Ratchet\ConnectionInterface $conn
90 | * @param string $id The unique ID of the RPC, required to respond to
91 | * @param string|Topic $topic The topic to execute the call against
92 | * @param array $params Call parameters received from the client
93 | */
94 | public function onCall(ConnectionInterface $conn, $id, $topic, array $params)
95 | {
96 | $this->console->info('onCall');
97 | $conn->callError($id, $topic, 'You are not allowed to make calls')->close();
98 | }
99 |
100 | /**
101 | * A client is attempting to publish content to a subscribed connections on a URI.
102 | *
103 | * @param \Ratchet\ConnectionInterface $conn
104 | * @param string|Topic $topic The topic the user has attempted to publish to
105 | * @param string $event Payload of the publish
106 | * @param array $exclude A list of session IDs the message should be excluded from (blacklist)
107 | * @param array $eligible A list of session Ids the message should be send to (whitelist)
108 | */
109 | public function onPublish(ConnectionInterface $conn, $topic, $event, array $exclude, array $eligible)
110 | {
111 | $this->console->info('onPublish');
112 | }
113 |
114 | /**
115 | * If there is an error with one of the sockets, or somewhere in the application where an Exception is thrown,
116 | * the Exception is sent back down the stack, handled by the Server and bubbled back up the application through this method.
117 | *
118 | * @param ConnectionInterface $conn
119 | * @param \Exception $e
120 | *
121 | * @throws \Exception
122 | */
123 | public function onError(ConnectionInterface $conn, \Exception $e)
124 | {
125 | $this->console->info('onError'.$e->getMessage());
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/src/RatchetWsServer.php:
--------------------------------------------------------------------------------
1 | clients = new \SplObjectStorage();
55 | $this->console = $console;
56 | }
57 |
58 | /**
59 | * Perform action on open.
60 | *
61 | * @param ConnectionInterface $conn [description]
62 | *
63 | * @return [type] [description]
64 | */
65 | public function onOpen(ConnectionInterface $conn)
66 | {
67 | $this->conn = $conn;
68 |
69 | $this->attach()->throttle()->limit();
70 | }
71 |
72 | protected function attach()
73 | {
74 | $this->clients->attach($this->conn);
75 | $this->console->info(sprintf('Connected: %d', $this->conn->resourceId));
76 |
77 | $this->connections = count($this->clients);
78 | $this->console->info(sprintf('%d %s', $this->connections, Str::plural('connection', $this->connections)));
79 |
80 | return $this;
81 | }
82 |
83 | /**
84 | * Throttle connections.
85 | *
86 | * @return [type] [description]
87 | */
88 | protected function throttle()
89 | {
90 | if ($this->isThrottled($this->conn, 'onOpen')) {
91 | $this->console->info(sprintf('Connection throttled: %d', $this->conn->resourceId));
92 | $this->conn->send(trans('ratchet::messages.tooManyConnectionAttempts'));
93 | $this->throttled = true;
94 | $this->conn->close();
95 | }
96 |
97 | return $this;
98 | }
99 |
100 | /**
101 | * Limit connections.
102 | *
103 | * @return [type] [description]
104 | */
105 | protected function limit()
106 | {
107 | if (($connectionLimit = config('ratchet.connectionLimit')) && $this->connections - 1 >= $connectionLimit) {
108 | $this->console->info(sprintf('To many connections: %d of %d', $this->connections - 1, $connectionLimit));
109 | $this->conn->send(trans('ratchet::messages.tooManyConnections'));
110 | $this->conn->close();
111 | }
112 |
113 | return $this;
114 | }
115 |
116 | /**
117 | * Check if the called function is throttled.
118 | *
119 | * @param [type] $conn [description]
120 | * @param [type] $setting [description]
121 | *
122 | * @return bool [description]
123 | */
124 | protected function isThrottled($conn, $setting)
125 | {
126 | $connectionThrottle = explode(':', config(sprintf('ratchet.throttle.%s', $setting)));
127 |
128 | return !Throttle::attempt(
129 | [
130 | 'ip' => $conn->remoteAddress,
131 | 'route' => $setting,
132 | ],
133 | (int) $connectionThrottle[0],
134 | (int) $connectionThrottle[1]
135 | );
136 | }
137 |
138 | /**
139 | * Perform action on message.
140 | *
141 | * @param ConnectionInterface $conn [description]
142 | * @param [type] $input [description]
143 | *
144 | * @return [type] [description]
145 | */
146 | public function onMessage(ConnectionInterface $conn, $input)
147 | {
148 | $this->console->comment(sprintf('Message from %d: %s', $conn->resourceId, $input));
149 |
150 | if ($this->isThrottled($conn, 'onMessage')) {
151 | $this->console->info(sprintf('Message throttled: %d', $conn->resourceId));
152 | $this->send($conn, trans('ratchet::messages.tooManyMessages'));
153 | $this->throttled = true;
154 |
155 | if (config('ratchet.abortOnMessageThrottle')) {
156 | $this->abort($conn);
157 | }
158 | }
159 | }
160 |
161 | /**
162 | * Perform action on close.
163 | *
164 | * @param ConnectionInterface $conn [description]
165 | *
166 | * @return [type] [description]
167 | */
168 | public function onClose(ConnectionInterface $conn)
169 | {
170 | $this->clients->detach($conn);
171 | $this->console->error(sprintf('Disconnected: %d', $conn->resourceId));
172 | }
173 |
174 | /**
175 | * Perform action on error.
176 | *
177 | * @param ConnectionInterface $conn [description]
178 | * @param Exception $exception [description]
179 | *
180 | * @return [type] [description]
181 | */
182 | public function onError(ConnectionInterface $conn, \Exception $exception)
183 | {
184 | $message = $exception->getMessage();
185 | $conn->close();
186 | $this->console->error(sprintf('Error: %s', $message));
187 | }
188 |
189 | /**
190 | * Close the current connection.
191 | *
192 | * @return [type] [description]
193 | */
194 | public function abort(ConnectionInterface $conn)
195 | {
196 | $this->clients->detach($conn);
197 | $conn->close();
198 | }
199 |
200 | /**
201 | * Send a message to the current connection.
202 | *
203 | * @param [type] $message [description]
204 | *
205 | * @return [type] [description]
206 | */
207 | public function send(ConnectionInterface $conn, $message)
208 | {
209 | $conn->send($message);
210 | }
211 |
212 | /**
213 | * Send a message to all connections.
214 | *
215 | * @param [type] $message [description]
216 | *
217 | * @return [type] [description]
218 | */
219 | public function sendAll($message)
220 | {
221 | foreach ($this->clients as $client) {
222 | $client->send($message);
223 | }
224 | }
225 | }
226 |
--------------------------------------------------------------------------------
/src/config/ratchet.php:
--------------------------------------------------------------------------------
1 | \Askedio\LaravelRatchet\Examples\Pusher::class,
15 | 'host' => '0.0.0.0', // Prepend tls:// to host address to enable SSL/TLS. Example: tls://0.0.0.0
16 | 'port' => '8080',
17 | 'connectionLimit' => false,
18 | 'throttle' => [
19 | 'onOpen' => '5:1',
20 | 'onMessage' => '20:1',
21 | ],
22 | 'abortOnMessageThrottle' => false,
23 | 'blackList' => [],
24 | 'zmq' => [
25 | 'host' => '127.0.0.1',
26 | 'port' => 5555,
27 | 'method' => \ZMQ::SOCKET_PULL,
28 | ],
29 | /**
30 | * Look up http://php.net/manual/en/context.ssl.php to configure SSL/TLS.
31 | */
32 | 'tls' => [
33 | // 'peer_name' => '',
34 | // 'verify_peer' => true,
35 | // 'verify_peer_name' => true,
36 | // 'allow_self_signed' => false,
37 | 'cafile' => env('SSL_CA_FILE', ''),
38 | 'capath' => env('SSL_CA_PATH', ''),
39 | 'local_cert' => env('SSL_PUBLIC_CERT', ''),
40 | 'local_pk' => env('SSL_PRIVATE_KEY', ''),
41 | 'passphrase' => env('SSL_PASSPHRASE', ''),
42 | ],
43 | ];
44 |
--------------------------------------------------------------------------------
/src/lang/en/messages.php:
--------------------------------------------------------------------------------
1 | json_encode(['error' => 'tooManyConnectionAttempts']),
15 | 'tooManyConnections' => json_encode(['error' => 'tooManyConnections']),
16 | 'tooManyMessages' => json_encode(['error' => 'tooManyMessages']),
17 | ];
18 |
--------------------------------------------------------------------------------
/tests/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * node index.js
3 | * - A simple echo test.
4 | */
5 |
6 |
7 | var WebSocket = require('ws');
8 | var ws = new WebSocket('ws://0.0.0.0:8080');
9 |
10 | ws.on('open', function open() {
11 | console.log('connected');
12 | });
13 |
14 | ws.on('close', function close() {
15 | console.log('disconnected');
16 | });
17 |
18 | ws.on('message', function message(data, flags) {
19 | console.log(data);
20 |
21 | setTimeout(function timeout() {
22 | ws.send(Date.now().toString(), {mask: true});
23 | }, 500);
24 | });
25 |
26 |
27 |
--------------------------------------------------------------------------------
/tests/pubsub.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------