# Workerman
[](https://gitter.im/walkor/Workerman?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=body_badge)
## What is it
Workerman is an asynchronous event driven PHP framework with high performance for easily building fast, scalable network applications.Supports HTTP, Websocket and other custom protocols. Supports libevent, HHVM, [ReactPHP](https://github.com/reactphp/react).
## Requires
PHP 5.3 or Higher
A POSIX compatible operating system (Linux, OSX, BSD)
POSIX and PCNTL extensions for PHP
## Installation
```
composer require workerman/workerman
```
## Basic Usage
### A websocket server
```php
<?php
require_once __DIR__ . '/vendor/autoload.php';
use Workerman\Worker;
// Create a Websocket server
$ws_worker = new Worker("websocket://0.0.0.0:2346");
// 4 processes
$ws_worker->count = 4;
// Emitted when new connection come
$ws_worker->onConnect = function($connection)
{
echo "New connection\n";
};
// Emitted when data received
$ws_worker->onMessage = function($connection, $data)
{
// Send hello $data
$connection->send('hello ' . $data);
};
// Emitted when connection closed
$ws_worker->onClose = function($connection)
{
echo "Connection closed\n";
};
// Run worker
Worker::runAll();
```
### An http server
```php
require_once __DIR__ . '/vendor/autoload.php';
use Workerman\Worker;
// #### http worker ####
$http_worker = new Worker("http://0.0.0.0:2345");
// 4 processes
$http_worker->count = 4;
// Emitted when data received
$http_worker->onMessage = function($connection, $data)
{
// $_GET, $_POST, $_COOKIE, $_SESSION, $_SERVER, $_FILES are available
var_dump($_GET, $_POST, $_COOKIE, $_SESSION, $_SERVER, $_FILES);
// send data to client
$connection->send("hello world \n");
};
// run all workers
Worker::runAll();
```
### A WebServer
```php
require_once __DIR__ . '/vendor/autoload.php';
use Workerman\WebServer;
use Workerman\Worker;
// WebServer
$web = new WebServer("http://0.0.0.0:80");
// 4 processes
$web->count = 4;
// Set the root of domains
$web->addRoot('www.your_domain.com', '/your/path/Web');
$web->addRoot('www.another_domain.com', '/another/path/Web');
// run all workers
Worker::runAll();
```
### A tcp server
```php
require_once __DIR__ . '/vendor/autoload.php';
use Workerman\Worker;
// #### create socket and listen 1234 port ####
$tcp_worker = new Worker("tcp://0.0.0.0:1234");
// 4 processes
$tcp_worker->count = 4;
// Emitted when new connection come
$tcp_worker->onConnect = function($connection)
{
echo "New Connection\n";
};
// Emitted when data received
$tcp_worker->onMessage = function($connection, $data)
{
// send data to client
$connection->send("hello $data \n");
};
// Emitted when new connection come
$tcp_worker->onClose = function($connection)
{
echo "Connection closed\n";
};
Worker::runAll();
```
### Custom protocol
Protocols/MyTextProtocol.php
```php
namespace Protocols;
/**
* User defined protocol
* Format Text+"\n"
*/
class MyTextProtocol
{
public static function input($recv_buffer)
{
// Find the position of the first occurrence of "\n"
$pos = strpos($recv_buffer, "\n");
// Not a complete package. Return 0 because the length of package can not be calculated
if($pos === false)
{
return 0;
}
// Return length of the package
return $pos+1;
}
public static function decode($recv_buffer)
{
return trim($recv_buffer);
}
public static function encode($data)
{
return $data."\n";
}
}
```
```php
require_once __DIR__ . '/vendor/autoload.php';
use Workerman\Worker;
// #### MyTextProtocol worker ####
$text_worker = new Worker("MyTextProtocol://0.0.0.0:5678");
$text_worker->onConnect = function($connection)
{
echo "New connection\n";
};
$text_worker->onMessage = function($connection, $data)
{
// send data to client
$connection->send("hello world \n");
};
$text_worker->onClose = function($connection)
{
echo "Connection closed\n";
};
// run all workers
Worker::runAll();
```
### Timer
```php
require_once __DIR__ . '/vendor/autoload.php';
use Workerman\Worker;
use Workerman\Lib\Timer;
$task = new Worker();
$task->onWorkerStart = function($task)
{
// 2.5 seconds
$time_interval = 2.5;
$timer_id = Timer::add($time_interval,
function()
{
echo "Timer run\n";
}
);
};
// run all workers
Worker::runAll();
```
### AsyncTcpConnection (tcp/ws/text/frame etc...)
```php
require_once __DIR__ . '/vendor/autoload.php';
use Workerman\Worker;
use Workerman\Connection\AsyncTcpConnection;
$worker = new Worker();
$worker->onWorkerStart = function()
{
// Websocket protocol for client.
$ws_connection = new AsyncTcpConnection("ws://echo.websocket.org:80");
$ws_connection->onConnect = function($connection){
$connection->send('hello');
};
$ws_connection->onMessage = function($connection, $data){
echo "recv: $data\n";
};
$ws_connection->onError = function($connection, $code, $msg){
echo "error: $msg\n";
};
$ws_connection->onClose = function($connection){
echo "connection closed\n";
};
$ws_connection->connect();
};
Worker::runAll();
```
### Async Mysql of ReactPHP
```
composer require react/mysql
```
```php
<?php
require_once __DIR__ . '/vendor/autoload.php';
use Workerman\Worker;
$worker = new Worker('tcp://0.0.0.0:6161');
$worker->onWorkerStart = function() {
global $mysql;
$loop = Worker::getEventLoop();
$mysql = new React\MySQL\Connection($loop, array(
'host' => '127.0.0.1',
'dbname' => 'dbname',
'user' => 'user',
'passwd' => 'passwd',
));
$mysql->on('error', function($e){
echo $e;
});
$mysql->connect(function ($e) {
if($e) {
echo $e;
} else {
echo "connect success\n";
}
});
};
$worker->onMessage = function($connection, $data) {
global $mysql;
$mysql->query('show databases' /*trim($data)*/, function ($command, $mysql) use ($connection) {
if ($command->hasError()) {
$error = $command->getError();
} else {
$results = $command->resultRows;
$fields = $command->resultFields;
$connection->send(json_encode($results));
}
});
};
Worker::runAll();
```
### Async Redis of ReactPHP
```
composer require clue/redis-react
```
```php
<?php
require_once __DIR__ . '/vendor/autoload.php';
use Clue\React\Redis\Factory;
use Clue\React\Redis\Client;
use Workerman\Worker;
$worker = new Worker('tcp://0.0.0.0:6161');
$worker->onWorkerStart = function() {
global $factory;
$loop = Worker::getEventLoop();
$factory = new Factory($loop);
};
$worker->onMessage = function($connection, $data) {
global $factory;
$factory->createClient('localhost:6379')->then(function (Client $client) use ($connection) {
$client->set('greeting', 'Hello world');
$client->append('greeting', '!');
$client->get('greeting')->then(function ($greeting) use ($connection){
// Hello world!
echo $greeting . PHP_EOL;
$connection->send($greeting);
});
$client->incr('invocation')->then(function ($n) use ($connection){
echo 'This is invocation #' . $n . PHP_EOL;
$connection->send($n);
});
});
};
Worker::runAll();
```
### Aysnc dns of ReactPHP
```
composer require react/dns
```
```php
require_once __DIR__ . '/vendor/autoload.php';
use Workerman\Worker;
$worker = new Worker('tcp://0.0.0.0:6161');
$worker->onWorkerStart = function() {
global $dns;
// Get event-loop.
$loop = Worker::getEventLoop();
$factory = new React\Dns\Resolver\Factory();
$dns = $factory->create('8.8.8.8', $loop);
};
$worker->onMessage = function($conn