puper / laravoole
Get 10x performance for Laravel on Swoole or Workerman
Requires
- php: >=5.5.16
- ext-posix: *
- laravel/framework: 5.1.* || 5.2.* || 5.3.*
Suggests
- ext-swoole: event-based extension for best performance
- workerman/workerman: event-based library without need for any extension
README
#Laravoole
Laravel on Swoole Or Workerman
10x faster than php-fpm
##Depends On
##Suggests
##Install
To get started, add laravoole to you composer.json file and run composer update
:
"garveen/laravoole": "~0.2"
or just run shell command:
composer require garveen/laravoole
Once composer done its job, you need to register Laravel service provider, in your config/app.php:
'providers' => [
...
Laravoole\LaravooleServiceProvider::class,
],
Notice: You should NOT use file session handler, because it is not stable at this environement. Use redis or other handler instead.
##Usage
php artisan laravoole [start | stop | reload | reload_task | restart | quit]
##Config
To generate config/laravoole.php
:
php artisan vendor:publish --provider="Laravoole\LaravooleServiceProvider"
Most of things can be configured with .env
, and you should use LARAVOOLE_{UPPER_CASE}
format, for example,
[ 'base_config' => [ 'host' => '0.0.0.0', ] ]
is equals with
LARAVOOLE_HOST=0.0.0.0
##Events
By now, there are only two events, laravoole.on_request
and laravoole.swoole.websocket.on_close
. You can handle events by editing EventServiceProvider
:
public function boot() { parent::boot(); \Event::listen('laravoole.on_request', function ($request) { \Log::info($request->segments()); }); }
##base_config
This section configures laravoole itself.
###mode
SwooleHttp
uses swoole to response http requests
SwooleFastCGI
uses swoole to response fastcgi requests (just like php-fpm)
SwooleWebSocket
uses swoole to response websocket requests AND http requests
WorkermanFastCGI
uses workerman to response fastcgi requests (just like php-fpm)
###pid_file
Defines a file that will store the process ID of the main process.
###deal_with_public
When using Http mode, you can turn on this option to let laravoole send static resources to clients. Use this ONLY when developing.
###host and port
Default host
is 127.0.0.1
, and port
is 9050
##handler_config
This section configures the backend, e.g. swoole
or workerman
.
###Swoole
As an example, if want to set worker_num to 8, you can set .env
:
LARAVOOLE_WORKER_NUM=8
or set config/laravoole.php
:
[ 'handler_config' => [ 'worker_num' => 8, ] ]
See Swoole's document:
###Workerman
As an example, if want to set worker_num to 8, you can set .env
:
LARAVOOLE_COUNT=8
or set config/laravoole.php
:
[ 'handler_config' => [ 'count' => 8, ] ]
See Workerman's document:
##Websocket Usage
###Subprotocols
See Mozilla's Document: Writing WebSocket server
The default subprotocol is jsonrpc, but has some different: params
is an object, and two more properties:
status
as HTTP status code
method
is the same as request's method
You can define your own subprotocol, by implements Laravoole\WebsocketCodec\CodecInterface
and add to config/laravoole.php
.
###Client Example:
<!DOCTYPE html> <meta charset="utf-8" /> <title>WebSocket Test</title> <style> p{word-wrap: break-word;} tr:nth-child(odd){background-color: #ccc} tr:nth-child(even){background-color: #eee} </style> <h2>WebSocket Test</h2> <table><tbody id="output"></tbody></table> <script> var wsUri = "ws://localhost:9050/websocket"; var protocols = ['jsonrpc']; var output = document.getElementById("output"); function send(message) { websocket.send(message); log('Sent', message); } function log(type, str) { str = str.replace(/&/g, '&').replace(/"/g, '"').replace(/'/g, ''').replace(/</g, '<').replace(/>/g, '>'); output.insertAdjacentHTML('beforeend', '<tr><td>' + type + '</td><td><p>' + htmlEscape(str) + '</p></td></tr>'); } websocket = new WebSocket(wsUri, protocols); websocket.onopen = function(evt) { log('Status', "Connection opened"); send(JSON.stringify({method: '/', params: {hello: 'world'}, id: 1})); setTimeout(function(){ websocket.close() },1000) }; websocket.onclose = function(evt) { log('Status', "Connection closed") }; websocket.onmessage = function(evt) { log('<span style="color: blue;">Received</span>', evt.data) }; websocket.onerror = function(evt) { log('<span style="color: red;">Error</span>', evt.data) }; </script> </html>
##Work with nginx
server { listen 80; server_name localhost; root /path/to/laravel/public; location / { try_files $uri $uri/ @laravoole; index index.html index.htm index.php; } # http location @laravoole { proxy_set_header Host $host:$server_port; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_http_version 1.1; proxy_pass http://127.0.0.1:9050; } # fastcgi location @laravoole { include fastcgi_params; fastcgi_pass 127.0.0.1:9050; } # websocket # send close if there has not an upgrade header map $http_upgrade $connection_upgrade { default upgrade; '' close; } location /websocket { proxy_connect_timeout 7d; proxy_send_timeout 7d; proxy_read_timeout 7d; proxy_pass http://127.0.0.1:9050; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; } }
#License MIT