首頁  >  文章  >  後端開發  >  workerman的基本用法(範例詳解)

workerman的基本用法(範例詳解)

藏色散人
藏色散人原創
2019-03-20 10:32:2819473瀏覽

workerman的基本用法(範例詳解)

workerman#是什麼?

Workerman是一個非同步事件驅動的PHP框架,具有高效能,可輕鬆建立快速,可擴展的網路應用程式。支援HTTP,Websocket,SSL和其他自訂協定。支援libevent,HHVMReactPHP

推薦:《workerman教學

#
PHP 5.3或更高版本
兼容POSIX的操作系统(Linux,OSX,BSD)
用于PHP的POSIX和PCNTL扩展

安裝

composer require workerman/workerman

基本用法

websocket伺服器

<?php
require_once __DIR__ . &#39;/vendor/autoload.php&#39;;
use Workerman\Worker;

// 创建一个Websocket服务器
$ws_worker = new Worker("websocket://0.0.0.0:2346");

$ws_worker->count = 4;

// 在新连接到来时发出
$ws_worker->onConnect = function($connection)
{
    echo "New connection\n";
 };

// 接收数据时发出
$ws_worker->onMessage = function($connection, $data)
{
    // Send hello $data
    $connection->send(&#39;hello &#39; . $data);
};

// 连接关闭时发出
$ws_worker->onClose = function($connection)
{
    echo "Connection closed\n";
};

// 运行worker
Worker::runAll();

#http伺服器

require_once __DIR__ . &#39;/vendor/autoload.php&#39;;
use Workerman\Worker;

// #### http worker ####
$http_worker = new Worker("http://0.0.0.0:2345");

$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("hello world \n");
};

// 运行所有workers
Worker::runAll();

WebServer

require_once __DIR__ . &#39;/vendor/autoload.php&#39;;
use Workerman\WebServer;
use Workerman\Worker;

// WebServer
$web = new WebServer("http://0.0.0.0:80");

$web->count = 4;

$web->addRoot(&#39;www.your_domain.com&#39;, &#39;/your/path/Web&#39;);
$web->addRoot(&#39;www.another_domain.com&#39;, &#39;/another/path/Web&#39;);

Worker::runAll();

TCP伺服器

require_once __DIR__ . &#39;/vendor/autoload.php&#39;;
use Workerman\Worker;

// #### 创建socket并监听1234端口 ####
$tcp_worker = new Worker("tcp://0.0.0.0:1234");

$tcp_worker->count = 4;

//在新连接到来时发出
$tcp_worker->onConnect = function($connection)
{
    echo "New Connection\n";
};

// 接收数据时发出
$tcp_worker->onMessage = function($connection, $data)
{
    // 发送数据给客户端
    $connection->send("hello $data \n");
};

// 在新连接到来时发出
$tcp_worker->onClose = function($connection)
{
    echo "Connection closed\n";
};

Worker::runAll();

啟用SSL

<?php
require_once __DIR__ . &#39;/vendor/autoload.php&#39;;
use Workerman\Worker;

// SSL环境
$context = array(
    &#39;ssl&#39; => array(
        &#39;local_cert&#39;  => &#39;/your/path/of/server.pem&#39;,
        &#39;local_pk&#39;    => &#39;/your/path/of/server.key&#39;,
        &#39;verify_peer&#39; => false,
    )
);

// 创建一个带有ssl的Websocket服务器。
$ws_worker = new Worker("websocket://0.0.0.0:2346", $context);

// 启用SSL。WebSocket+SSL意味着安全的WebSocket (wss://)。
//类似的Https方法等等。
$ws_worker->transport = &#39;ssl&#39;;

$ws_worker->onMessage = function($connection, $data)
{
    // 发送hello $data
    $connection->send(&#39;hello &#39; . $data);
};

Worker::runAll();

自訂協定

Protocols/MyTextProtocol.php

namespace Protocols;
/**
 * 用户定义的协议
*格式文本+“\ n”
 */
class MyTextProtocol
{
    public static function input($recv_buffer)
    {
        // 找到“\n”第一个出现的位置
        $pos = strpos($recv_buffer, "\n");
        // 不是一个完整的package。返回0,因为package的长度无法计算
        if($pos === false)
        {
            return 0;
        }
        // 返回package的长度
        return $pos+1;
    }

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

    public static function encode($data)
    {
        return $data."\n";
    }
}
require_once __DIR__ . &#39;/vendor/autoload.php&#39;;
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)
{
    // 发送数据给客户端
    $connection->send("hello world \n");
};

$text_worker->onClose = function($connection)
{
    echo "Connection closed\n";
};

// 运行所有workers
Worker::runAll();

計時器

#
require_once __DIR__ . &#39;/vendor/autoload.php&#39;;
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 "Timer run\n";
        }
    );
};

//运行
Worker::runAll();

AsyncTcpConnection(tcp / ws / text / frame等...)

require_once __DIR__ . &#39;/vendor/autoload.php&#39;;
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(&#39;hello&#39;);
    };
    $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();

ReactPHP的非同步Mysql

#
composer require react/mysql
<?php
require_once __DIR__ . &#39;/vendor/autoload.php&#39;;
use Workerman\Worker;

$worker = new Worker(&#39;tcp://0.0.0.0:6161&#39;);
$worker->onWorkerStart = function() {
    global $mysql;
    $loop  = Worker::getEventLoop();
    $mysql = new React\MySQL\Connection($loop, array(
        &#39;host&#39;   => &#39;127.0.0.1&#39;,
        &#39;dbname&#39; => &#39;dbname&#39;,
        &#39;user&#39;   => &#39;user&#39;,
        &#39;passwd&#39; => &#39;passwd&#39;,
    ));
    $mysql->on(&#39;error&#39;, 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(&#39;show databases&#39; /*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();

ReactPHP的Async Redis

composer require clue/redis-react
<?php
require_once __DIR__ . &#39;/vendor/autoload.php&#39;;
use Clue\React\Redis\Factory;
use Clue\React\Redis\Client;
use Workerman\Worker;

$worker = new Worker(&#39;tcp://0.0.0.0:6161&#39;);

$worker->onWorkerStart = function() {
    global $factory;
    $loop    = Worker::getEventLoop();
    $factory = new Factory($loop);
};

$worker->onMessage = function($connection, $data) {
    global $factory;
    $factory->createClient(&#39;localhost:6379&#39;)->then(function (Client $client) use ($connection) {
        $client->set(&#39;greeting&#39;, &#39;Hello world&#39;);
        $client->append(&#39;greeting&#39;, &#39;!&#39;);

        $client->get(&#39;greeting&#39;)->then(function ($greeting) use ($connection){
            // Hello world!
            echo $greeting . PHP_EOL;
            $connection->send($greeting);
        });

        $client->incr(&#39;invocation&#39;)->then(function ($n) use ($connection){
            echo &#39;This is invocation #&#39; . $n . PHP_EOL;
            $connection->send($n);
        });
    });
};

Worker::runAll();

Aysnc dns的ReactPHP

composer require react/dns
require_once __DIR__ . &#39;/vendor/autoload.php&#39;;
use Workerman\Worker;
$worker = new Worker(&#39;tcp://0.0.0.0:6161&#39;);
$worker->onWorkerStart = function() {
    global   $dns;
    // Get event-loop.
    $loop    = Worker::getEventLoop();
    $factory = new React\Dns\Resolver\Factory();
    $dns     = $factory->create(&#39;8.8.8.8&#39;, $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();

ReactPHP的Http客戶端

composer require react/http-client
<?php
require_once __DIR__ . &#39;/vendor/autoload.php&#39;;
use Workerman\Worker;

$worker = new Worker(&#39;tcp://0.0.0.0:6161&#39;);

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

Worker::runAll();

ReactPHP的Http客戶端

composer require react/zmq
<?php
require_once __DIR__ . &#39;/vendor/autoload.php&#39;;
use Workerman\Worker;
$worker = new Worker(&#39;text://0.0.0.0:6161&#39;);
$worker->onWorkerStart = function() {
    global   $pull;
    $loop    = Worker::getEventLoop();
    $context = new React\ZMQ\Context($loop);
    $pull    = $context->getSocket(ZMQ::SOCKET_PULL);
    $pull->bind(&#39;tcp://127.0.0.1:5555&#39;);
    $pull->on(&#39;error&#39;, function ($e) {
        var_dump($e->getMessage());
    });
    $pull->on(&#39;message&#39;, function ($msg) {
        echo "Received: $msg\n";
    });
};
Worker::runAll();

ReactPHP的ZMQ

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

$worker = new Worker(&#39;text://0.0.0.0:6161&#39;);

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

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

Worker::runAll();

react的STOMP

php start.php start 
php start.php start -d
php start.php status [object Object]

workerman的基本用法(範例詳解)可用指令

php start.php connections
php start.php stop 
php start.php restart 
php start.php reload

#
CPU:      Intel(R) Core(TM) i3-3220 CPU @ 3.30GHz and 4 processors totally
Memory:   8G
OS:       Ubuntu 14.04 LTS
Software: ab
PHP:      5.5.9
<?php
use Workerman\Worker;
$worker = new Worker(&#39;tcp://0.0.0.0:1234&#39;);
$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)

程式碼

rrreee

結果

rrreee###本篇文章是關於###workerman###的相關介紹,希望對需要的朋友有幫助! ###

以上是workerman的基本用法(範例詳解)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn