1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/beautyz-workerman

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
README.md 15 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
gitlife-traslator Отправлено 25.11.2024 22:48 19d73b6

Workerman

Что это такое

Workerman — это асинхронный событийно-ориентированный PHP-фреймворк с высокой производительностью, который позволяет легко создавать быстрые и масштабируемые сетевые приложения. Поддерживает HTTP, WebSocket, SSL и другие пользовательские протоколы. Поддерживает libevent, HHVM, ReactPHP.

Требования

  • PHP 5.3 или выше.
  • POSIX-совместимая операционная система (Linux, OSX, BSD).
  • Расширения PHP: POSIX и PCNTL.

Установка

composer require workerman/workerman

Основное использование

Веб-сокет сервер

<?php
require_once __DIR__ . '/vendor/autoload.php';
use Workerman\Worker;

// Создаём веб-сокет-сервер
$ws_worker = new Worker("websocket://0.0.0.0:2346");

// 4 процесса
$ws_worker->count = 4;

// Выдаётся при новом соединении
$ws_worker->onConnect = function($connection) {
    echo "Новое соединение\n";
};

// Выдаётся при получении данных
$ws_worker->onMessage = function($connection, $data) {
    // Отправляем приветствие $data
    $connection->send('привет ' . $data);
};

// Выдаётся при закрытии соединения
$ws_worker->onClose = function($connection) {
    echo "Соединение закрыто\n";
};

// Запускаем рабочий процесс
Worker::runAll();

HTTP-сервер

require_once __DIR__ . '/vendor/autoload.php';
use Workerman\Worker;

// #### HTTP-рабочий ####
$http_worker = new Worker("http://0.0.0.0:2345");

// 4 процесса
$http_worker->count = 4;

// Выдаётся при получении данных
$http_worker->onMessage = function($connection, $data) {
    // $_GET, $_POST, $_COOKIE, $_SESSION, $_SERVER, $_FILES доступны
    var_dump($_GET, $_POST, $_COOKIE, $_SESSION, $_SERVER, $_FILES);
    // отправляем данные клиенту
    $connection->send("привет мир \n");
};

// запускаем все рабочие процессы
Worker::runAll();

Веб-сервер

require_once __DIR__ . '/vendor/autoload.php';
use Workerman\WebServer;
use Workerman\Worker;

// Веб-сервер
$web = new WebServer("http://0.0.0.0:80");

// 4 процесса
$web->count = 4;

// Устанавливаем корень доменов
$web->addRoot('www.your_domain.com', '/your/path/Web');
$web->addRoot('www.another_domain.com', '/another/path/Web');
// запускаем все рабочие процессы
Worker::runAll();

TCP-сервер

require_once __DIR__ . '/vendor/autoload.php';
use Workerman\Worker;

// #### создаём сокет и слушаем порт 1234 ####
$tcp_worker = new Worker("tcp://0.0.0.0:1234");

// 4 процесса
$tcp_worker->count = 4;

// Выдаётся при новом подключении
$tcp_worker->onConnect = function($connection) {
    echo "Новое подключение\n";
};

// Выдаётся при получении данных
$tcp_worker->onMessage = function($connection, $data) {
    // отправляем данные клиенту
    $connection->send("привет $data \n");
};

// Выдаётся при новом подключении
$tcp_worker->onClose = function($connection) {
    echo "Подключение закрыто\n";
};

Worker::runAll();

Включение SSL

<?php
require_once __DIR__ . '/vendor/autoload.php';
use Workerman\Worker;

// Контекст SSL.
$context = array(
    'ssl' => array(
        'local_cert'  => '/ваш/путь/сервера.pem',
        'local_pk'    => '/ваш/путь/сервера.key',
        'verify_peer' => false,
    )
);

// Создание веб-сокета с контекстом SSL.
$ws_worker = new Worker("websocket://0.0.0.0:2346", $context);

// Включаем SSL. Веб-сокеты + SSL означают защищённые веб-сокеты (wss://). **Подходы для HTTPS и т. д.**

*ws_worker->transport = 'ssl';*

*ws_worker->onMessage = function($connection, $data)*
{
    // Отправить приветствие $data
    $connection->send('hello ' . $data);
};

Worker::runAll();

**Пользовательский протокол**

Protocols/MyTextProtocol.php

namespace Protocols; /**

  • Пользовательский протокол

  • Формат Текст + "\n" */ class MyTextProtocol { public static function input($recv_buffer) { // Найти позицию первого вхождения "\n" $pos = strpos($recv_buffer, "\n"); // Не полный пакет. Возвращаем 0, потому что длину пакета рассчитать невозможно if ($pos === false) { return 0; } // Возвращаем длину пакета return $pos + 1; }

    public static function decode($recv_buffer) { return trim($recv_buffer); }

    public static function encode($data) { return $data."\n"; } }

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 "Новое соединение\n"; };

$text_worker->onMessage = function($connection, $data) { // отправить данные клиенту $connection->send("привет мир \n"); };

$text_worker->onClose = function($connection) { echo "Соединение закрыто\n"; };

// запустить всех рабочих Worker::runAll();


**Таймер**

require_once DIR . '/vendor/autoload.php'; use Workerman\Worker; use Workerman\Lib\Timer;

$task = new Worker(); $task->onWorkerStart = function($task) { // 2,5 секунды $time_interval = 2.5; $timer_id = Timer::add($time_interval, function() { echo "Таймер запущен\n"; } ); };

// Запустить всех рабочих Worker::runAll();


**AsyncTcpConnection (tcp/ws/text/frame и т.д.)**

require_once DIR . '/vendor/autoload.php'; use Workerman\Worker; use Workerman\Connection\AsyncTcpConnection;

$worker = new Worker(); $worker->onWorkerStart = function() { // Протокол Websocket для клиента. $ws_connection = new AsyncTcpConnection("ws://echo.websocket.org:80"); $ws_connection->onConnect = function($connection){ $connection->send('привет'); }; $ws_connection->onMessage = function($connection, $data){ echo "получено: $data\n"; }; $ws_connection->onError = function($connection, $code, $msg){ echo "ошибка: $msg\n"; }; $ws_connection->onClose = function($connection){ echo "соединение закрыто\n"; }; $ws_connection->connect(); }; Worker::runAll();


**Асинхронный MySQL от 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 "успешное подключение\n";
        }
    });
};
$worker->onMessage = function($connection, $data) {
    global $mysql;
    $mysql->query('показать базы данных' /*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();

Асинхронный Redis от ReactPHP

composer require clue/redis-react

<?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;
``` **Код на языке PHP:**

```php
$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();

Код на языке PHP:

composer require react/dns
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($connection, $host) {
    global $dns;
    $host = trim($host);
    $dns->resolve($host)->then(function($ip) use($host, $connection) {
        $connection->send("$host: $ip");
    },function($e) use($host, $connection){
        $connection->send("$host: {$e->getMessage()}");
    });
};

Worker::runAll();

Код на языке PHP:

<?php
require_once __DIR__ . '/vendor/autoload.php';
use Workerman\Worker;

$worker = new Worker('tcp://0.0.0.0:6161');

$worker->onMessage = function($connection, $host) {
    $loop    = Worker::getEventLoop();
    $client  = new \React\HttpClient\Client($loop);
    $request = $client->request('GET', trim($host));
    $request->on('error', function(Exception $e) use ($connection) {
        $connection->send($e);
    });
    $request->on('response', function ($response) use ($connection) {
        $response->on('data', function ($data) use ($connection) {
            $connection->send($data);
        });
    });
    $request->end();
};

Worker::runAll();

Код на языке PHP:

composer require react/zmq
<?php
require_once __DIR__ . '/vendor/autoload.php';
use Workerman\Worker;

$worker = new Worker('text://0.0.0.0:6161');

$worker->onWorkerStart = function() {
    global   $pull;
    $loop    = Worker::getEventLoop();
    $context = new React\ZMQ\Context($loop);
    $pull    = $context->getSocket(ZMQ::SOCKET_PULL);
    $pull->bind('tcp://127.0.0.1:5555');

    $pull->on('error', function ($e) {
        var_dump($e->getMessage());
    });

    $pull->on('message', function ($msg) {
        echo "Received: $msg\n";
    });
};

Worker::runAll();

Код на языке PHP:

composer require react/stomp
<?php
require_once __DIR__ . '/vendor/autoload.php';
use Workerman\Worker;

$worker = new Worker('text://0.0.0.0:6161');

$worker->onWorkerStart = function() {
    global   $client;
    $loop    = Worker::getEventLoop();
    $factory = new React\Stomp\Factory($loop);
    $client  = $factory->createClient(array('vhost' => '/', 'login' => 'guest', 'passcode' => 'guest'));

    $client
        ->connect()
        ->then(function ($client) use ($loop) {
            $client->subscribe('/topic/foo', function ($frame) {
                echo "Message received: {$frame->body}\n";
            });
        });
};

Worker::runAll();
``` **Бенчмарки**

CPU: Intel(R) Core(TM) i3-3220 CPU @ 3.30GHz и 4 процессора всего Memory: 8G OS: Ubuntu 14.04 LTS Software: ab PHP: 5.5.9


**Код**
```php
<?php
use Workerman\Worker;
$worker = new Worker('tcp://0.0.0.0:1234');
$worker->count=3;
$worker->onMessage = function($connection, $data) {
    $connection->send("HTTP/1.1 200 OK\r\nConnection: keep-alive\r\nServer: workerman\r\nContent-Length: 5\r\n\r\nhello");
};
Worker::runAll();

Результат

ab -n1000000 -c100 -k http://127.0.0.1:1234/
This is ApacheBench, Version 2.3 <$Revision: 1528965 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient)
Completed 100000 requests
Completed 200000 requests
Completed 300000 requests
Completed 400000 requests
Completed 500000 requests
Completed 600000 requests
Completed 700000 requests
Completed 800000 requests
Completed 900000 requests
Completed 1000000 requests
Finished 1000000 requests


Server Software:        workerman/3.1.4
Server Hostname:        127.0.0.1
Server Port:            1234

Document Path:          /
Document Length:        5 bytes

Concurrency Level:      100
Time taken for tests:   7.240 seconds
Complete requests:      1000000
Failed requests:        0
Keep-Alive requests:    1000000
Total transferred:      73000000 bytes
HTML transferred:       5000000 bytes
Requests per second:    138124.14 [#/sec] (mean)
Time per request:       0.724 [ms] (mean)
Time per request:       0.007 [ms] (mean, across all concurrent requests)
Transfer rate:          9846.74 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.0      0       5
Processing:     0    1   0.2      1       9
Waiting:        0    1   0.2      1       9
Total:          0    1   0.2      1       9

Percentage of the requests served within a certain time (ms)
  50%      1
  66%      1
  75%      1
  80%      1
  90%      1
  95%      1
  98%      1
  99%      1
 100%      9 (longest request)

Другие ссылки с Workerman

PHPSocket.IO
php-socks5
php-http-proxy

Пожертвовать

ЛИЦЕНЗИЯ

Workerman выпущен под лицензией MIT (https://github.com/walkor/workerman/blob/master/MIT-LICENSE.txt).

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/beautyz-workerman.git
git@api.gitlife.ru:oschina-mirror/beautyz-workerman.git
oschina-mirror
beautyz-workerman
beautyz-workerman
master