当前位置:首页 > PHP教程 > php高级应用 > 列表

workerman的基本用法(示例详解)

发布:smiling 来源: PHP粉丝网  添加日期:2020-02-04 18:17:05 浏览: 评论:0 

workerman是什么?

Workerman是一个异步事件驱动的PHP框架,具有高性能,可轻松构建快速,可扩展的网络应用程序。支持HTTP,Websocket,SSL和其他自定义协议。支持libevent,HHVM,ReactPHP。

要求:

PHP 5.3或更高版本

兼容POSIX的操作系统(Linux,OSX,BSD)

用于PHP的POSIX和PCNTL扩展

安装:

composer require workerman/workerman

基本用法:

websocket服务器

  1.  
  2. require_once __DIR__ . '/vendor/autoload.php'; 
  3.  
  4. use Workerman\Worker; 
  5.  
  6.  
  7.  
  8. // 创建一个Websocket服务器 
  9.  
  10. $ws_worker = new Worker("websocket://0.0.0.0:2346"); 
  11.  
  12.  
  13.  
  14. $ws_worker->count = 4; 
  15.  
  16.  
  17.  
  18. // 在新连接到来时发出 
  19.  
  20. $ws_worker->onConnect = function($connection) 
  21.  
  22. { 
  23.  
  24.     echo "New connection\n"; 
  25.  
  26.  }; 
  27.  
  28.  
  29.  
  30. // 接收数据时发出 
  31.  
  32. $ws_worker->onMessage = function($connection, $data) 
  33.  
  34. { 
  35.  
  36.     // Send hello $data 
  37.  
  38.     $connection->send('hello ' . $data); 
  39.  
  40. }; 
  41.  
  42.  
  43.  
  44. // 连接关闭时发出 
  45.  
  46. $ws_worker->onClose = function($connection) 
  47.  
  48. { 
  49.  
  50.     echo "Connection closed\n"; 
  51.  
  52. }; 
  53.  
  54.  
  55. // 运行worker 
  56.  
  57. Worker::runAll(); 

http服务器

  1. require_once __DIR__ . '/vendor/autoload.php'; 
  2.  
  3. use Workerman\Worker; 
  4.  
  5.  
  6.  
  7. // #### http worker #### 
  8.  
  9. $http_worker = new Worker("http://0.0.0.0:2345"); 
  10.  
  11.  
  12.  
  13. $http_worker->count = 4; 
  14.  
  15.  
  16.  
  17. // 接收数据时发出 
  18.  
  19. $http_worker->onMessage = function($connection, $data) 
  20.  
  21. { 
  22.  
  23.     //$_GET、$_POST、$_COOKIE、$_SESSION、$_SERVER、$_FILES都是可用的 
  24.  
  25.     var_dump($_GET, $_POST, $_COOKIE, $_SESSION, $_SERVER, $_FILES); 
  26.  
  27.     // 发送数据给客户端 
  28.  
  29.     $connection->send("hello world \n"); 
  30.  
  31. }; 
  32.  
  33. // 运行所有workers 
  34.  
  35. Worker::runAll(); 

WebServer

  1. require_once __DIR__ . '/vendor/autoload.php'; 
  2.  
  3. use Workerman\WebServer; 
  4.  
  5. use Workerman\Worker; 
  6.  
  7.  
  8.  
  9. // WebServer 
  10.  
  11. $web = new WebServer("http://0.0.0.0:80"); 
  12.  
  13.  
  14.  
  15. $web->count = 4; 
  16.  
  17.  
  18.  
  19. $web->addRoot('www.your_domain.com', '/your/path/Web'); 
  20.  
  21. $web->addRoot('www.another_domain.com', '/another/path/Web'); 
  22.  
  23.  
  24.  
  25. Worker::runAll(); 

TCP服务器

  1. require_once __DIR__ . '/vendor/autoload.php'; 
  2.  
  3. use Workerman\Worker; 
  4.  
  5.  
  6.  
  7. // #### 创建socket并监听1234端口 #### 
  8.  
  9. $tcp_worker = new Worker("tcp://0.0.0.0:1234"); 
  10.  
  11.  
  12.  
  13. $tcp_worker->count = 4; 
  14.  
  15.  
  16.  
  17. //在新连接到来时发出 
  18.  
  19. $tcp_worker->onConnect = function($connection) 
  20.  
  21. { 
  22.  
  23.     echo "New Connection\n"; 
  24.  
  25. }; 
  26.  
  27.  
  28.  
  29. // 接收数据时发出 
  30.  
  31. $tcp_worker->onMessage = function($connection, $data) 
  32.  
  33. { 
  34.  
  35.     // 发送数据给客户端 
  36.  
  37.     $connection->send("hello $data \n"); 
  38.  
  39. }; 
  40.  
  41.  
  42.  
  43. // 在新连接到来时发出 
  44.  
  45. $tcp_worker->onClose = function($connection) 
  46.  
  47. { 
  48.  
  49.     echo "Connection closed\n"; 
  50.  
  51. }; 
  52.  
  53.  
  54.  
  55. Worker::runAll(); 

启用SSL

  1.  
  2. require_once __DIR__ . '/vendor/autoload.php'; 
  3.  
  4. use Workerman\Worker; 
  5.  
  6. // SSL环境 
  7.  
  8. $context = array( 
  9.  
  10.     'ssl' => array( 
  11.  
  12.         'local_cert'  => '/your/path/of/server.pem', 
  13.  
  14.         'local_pk'    => '/your/path/of/server.key', 
  15.  
  16.         'verify_peer' => false, 
  17.  
  18.     ) 
  19.  
  20. ); 
  21.  
  22. // 创建一个带有ssl的Websocket服务器。 
  23.  
  24. $ws_worker = new Worker("websocket://0.0.0.0:2346", $context); 
  25.   
  26. // 启用SSL。WebSocket+SSL意味着安全的WebSocket (wss://)。 
  27.  
  28. //类似的Https方法等等。 
  29.  
  30. $ws_worker->transport = 'ssl'; 
  31.   
  32. $ws_worker->onMessage = function($connection, $data) 
  33.  
  34. { 
  35.  
  36.     // 发送hello $data 
  37.  
  38.     $connection->send('hello ' . $data); 
  39.  
  40. }; 
  41.  
  42. Worker::runAll(); 

自定义协议

Protocols/MyTextProtocol.php

  1. namespace Protocols; 
  2.  
  3. /** 
  4.  
  5.  * 用户定义的协议 
  6.  
  7. *格式文本+“\ n” 
  8.  
  9.  */ 
  10.  
  11. class MyTextProtocol 
  12.  
  13. { 
  14.  
  15.     public static function input($recv_buffer) 
  16.  
  17.     { 
  18.  
  19.         // 找到“\n”第一个出现的位置 
  20.  
  21.         $pos = strpos($recv_buffer, "\n"); 
  22.  
  23.         // 不是一个完整的package。返回0,因为package的长度无法计算 
  24.  
  25.         if($pos === false) 
  26.  
  27.         { 
  28.  
  29.             return 0; 
  30.  
  31.         } 
  32.  
  33.         // 返回package的长度 
  34.  
  35.         return $pos+1; 
  36.  
  37.     } 
  38.  
  39.  
  40.  
  41.     public static function decode($recv_buffer) 
  42.  
  43.     { 
  44.  
  45.         return trim($recv_buffer); 
  46.  
  47.     } 
  48.  
  49.  
  50.  
  51.     public static function encode($data) 
  52.  
  53.     { 
  54.  
  55.         return $data."\n"; 
  56.  
  57.     } 
  58.  
  59. } 
  60.  
  61. require_once __DIR__ . '/vendor/autoload.php'; 
  62.  
  63. use Workerman\Worker; 
  64.  
  65. // #### MyTextProtocol worker #### 
  66.  
  67. $text_worker = new Worker("MyTextProtocol://0.0.0.0:5678"); 
  68.  
  69. $text_worker->onConnect = function($connection) 
  70.  
  71. { 
  72.  
  73.     echo "New connection\n"; 
  74.  
  75. }; 
  76.  
  77. $text_worker->onMessage =  function($connection, $data) 
  78.  
  79. { 
  80.  
  81.     // 发送数据给客户端 
  82.  
  83.     $connection->send("hello world \n"); 
  84.  
  85. }; 
  86.  
  87. $text_worker->onClose = function($connection) 
  88.  
  89. { 
  90.  
  91.     echo "Connection closed\n"; 
  92.  
  93. }; 
  94.  
  95. // 运行所有workers 
  96.  
  97. Worker::runAll(); 

计时器

  1. require_once __DIR__ . '/vendor/autoload.php'; 
  2.  
  3. use Workerman\Worker; 
  4.  
  5. use Workerman\Lib\Timer; 
  6.  
  7.  
  8.  
  9. $task = new Worker(); 
  10.  
  11. $task->onWorkerStart = function($task) 
  12.  
  13. { 
  14.  
  15.     // 2.5秒 
  16.  
  17.     $time_interval = 2.5;  
  18.  
  19.     $timer_id = Timer::add($time_interval,  
  20.  
  21.         function() 
  22.  
  23.         { 
  24.  
  25.             echo "Timer run\n"; 
  26.  
  27.         } 
  28.  
  29.     ); 
  30.  
  31. }; 
  32.  
  33. //运行 
  34.  
  35. Worker::runAll(); 

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

  1. require_once __DIR__ . '/vendor/autoload.php'; 
  2.  
  3. use Workerman\Worker; 
  4.  
  5. use Workerman\Connection\AsyncTcpConnection; 
  6.  
  7.  
  8. $worker = new Worker(); 
  9.  
  10. $worker->onWorkerStart = function() 
  11.  
  12. { 
  13.  
  14.     //客户端Websocket协议。 
  15.  
  16.     $ws_connection = new AsyncTcpConnection("ws://echo.websocket.org:80"); 
  17.  
  18.     $ws_connection->onConnect = function($connection){ 
  19.  
  20.         $connection->send('hello'); 
  21.  
  22.     }; 
  23.  
  24.     $ws_connection->onMessage = function($connection, $data){ 
  25.  
  26.         echo "recv: $data\n"; 
  27.  
  28.     }; 
  29.  
  30.     $ws_connection->onError = function($connection, $code, $msg){ 
  31.  
  32.         echo "error: $msg\n"; 
  33.  
  34.     }; 
  35.  
  36.     $ws_connection->onClose = function($connection){ 
  37.  
  38.         echo "connection closed\n"; 
  39.  
  40.     }; 
  41.  
  42.     $ws_connection->connect(); 
  43.  
  44. }; 
  45.  
  46. Worker::runAll(); 

ReactPHP的异步Mysql

composer require react/mysql

  1.  
  2. require_once __DIR__ . '/vendor/autoload.php'; 
  3.  
  4. use Workerman\Worker; 
  5.  
  6.  
  7.  
  8. $worker = new Worker('tcp://0.0.0.0:6161'); 
  9.  
  10. $worker->onWorkerStart = function() { 
  11.  
  12.     global $mysql; 
  13.  
  14.     $loop  = Worker::getEventLoop(); 
  15.  
  16.     $mysql = new React\MySQL\Connection($loop, array( 
  17.  
  18.         'host'   => '127.0.0.1', 
  19.  
  20.         'dbname' => 'dbname', 
  21.  
  22.         'user'   => 'user', 
  23.  
  24.         'passwd' => 'passwd', 
  25.  
  26.     )); 
  27.  
  28.     $mysql->on('error', function($e){ 
  29.  
  30.         echo $e; 
  31.  
  32.     }); 
  33.  
  34.     $mysql->connect(function ($e) { 
  35.  
  36.         if($e) { 
  37.  
  38.             echo $e; 
  39.  
  40.         } else { 
  41.  
  42.             echo "connect success\n"; 
  43.  
  44.         } 
  45.  
  46.     }); 
  47.  
  48. }; 
  49.  
  50. $worker->onMessage = function($connection, $data) { 
  51.  
  52.     global $mysql; 
  53.  
  54.     $mysql->query('show databases' /*trim($data)*/, function ($command, $mysql) use ($connection) { 
  55.  
  56.         if ($command->hasError()) { 
  57.  
  58.             $error = $command->getError(); 
  59.  
  60.         } else { 
  61.  
  62.             $results = $command->resultRows; 
  63.  
  64.             $fields  = $command->resultFields; 
  65.  
  66.             $connection->send(json_encode($results)); 
  67.  
  68.         } 
  69.  
  70.     }); 
  71.  
  72. }; 
  73.  
  74. Worker::runAll(); 

ReactPHP的Async Redis

composer require clue/redis-react

  1.  
  2. require_once __DIR__ . '/vendor/autoload.php'; 
  3.  
  4. use Clue\React\Redis\Factory; 
  5.  
  6. use Clue\React\Redis\Client; 
  7.  
  8. use Workerman\Worker; 
  9.  
  10.  
  11.  
  12. $worker = new Worker('tcp://0.0.0.0:6161'); 
  13.  
  14.  
  15.  
  16. $worker->onWorkerStart = function() { 
  17.  
  18.     global $factory; 
  19.  
  20.     $loop    = Worker::getEventLoop(); 
  21.  
  22.     $factory = new Factory($loop); 
  23.  
  24. }; 
  25.  
  26.  
  27.  
  28. $worker->onMessage = function($connection, $data) { 
  29.  
  30.     global $factory; 
  31.  
  32.     $factory->createClient('localhost:6379')->then(function (Client $client) use ($connection) { 
  33.  
  34.         $client->set('greeting', 'Hello world'); 
  35.  
  36.         $client->append('greeting', '!'); 
  37.  
  38.  
  39.  
  40.         $client->get('greeting')->then(function ($greeting) use ($connection){ 
  41.  
  42.             // Hello world! 
  43.  
  44.             echo $greeting . PHP_EOL; 
  45.  
  46.             $connection->send($greeting); 
  47.  
  48.         }); 
  49.  
  50.  
  51.  
  52.         $client->incr('invocation')->then(function ($n) use ($connection){ 
  53.  
  54.             echo 'This is invocation #' . $n . PHP_EOL; 
  55.  
  56.             $connection->send($n); 
  57.  
  58.         }); 
  59.  
  60.     }); 
  61.  
  62. }; 
  63.  
  64. Worker::runAll(); 

Aysnc dns的ReactPHP

composer require react/dns

  1. require_once __DIR__ . '/vendor/autoload.php'; 
  2.  
  3. use Workerman\Worker; 
  4.  
  5. $worker = new Worker('tcp://0.0.0.0:6161'); 
  6.  
  7. $worker->onWorkerStart = function() { 
  8.  
  9.     global   $dns; 
  10.  
  11.     // Get event-loop. 
  12.  
  13.     $loop    = Worker::getEventLoop(); 
  14.  
  15.     $factory = new React\Dns\Resolver\Factory(); 
  16.  
  17.     $dns     = $factory->create('8.8.8.8', $loop); 
  18.  
  19. }; 
  20.  
  21. $worker->onMessage = function($connection, $host) { 
  22.  
  23.     global $dns; 
  24.  
  25.     $host = trim($host); 
  26.  
  27.     $dns->resolve($host)->then(function($ip) use($host, $connection) { 
  28.  
  29.         $connection->send("$host: $ip"); 
  30.  
  31.     },function($e) use($host, $connection){ 
  32.  
  33.         $connection->send("$host: {$e->getMessage()}"); 
  34.  
  35.     }); 
  36.  
  37. }; 
  38.  
  39.  
  40. Worker::runAll(); 

ReactPHP的Http客户端

composer require react/http-client

  1.  
  2. require_once __DIR__ . '/vendor/autoload.php'; 
  3.  
  4. use Workerman\Worker; 
  5.  
  6.  
  7. $worker = new Worker('tcp://0.0.0.0:6161'); 
  8.  
  9.  
  10. $worker->onMessage = function($connection, $host) { 
  11.  
  12.     $loop    = Worker::getEventLoop(); 
  13.  
  14.     $client  = new \React\HttpClient\Client($loop); 
  15.  
  16.     $request = $client->request('GET', trim($host)); 
  17.  
  18.     $request->on('error', function(Exception $e) use ($connection) { 
  19.  
  20.         $connection->send($e); 
  21.  
  22.     }); 
  23.  
  24.     $request->on('response', function ($response) use ($connection) { 
  25.  
  26.         $response->on('data', function ($data) use ($connection) { 
  27.  
  28.             $connection->send($data); 
  29.  
  30.         }); 
  31.  
  32.     }); 
  33.  
  34.     $request->end(); 
  35.  
  36. }; 
  37.  
  38.  
  39. Worker::runAll(); 

ReactPHP的ZMQ

composer require react/zmq

  1.  
  2. require_once __DIR__ . '/vendor/autoload.php'; 
  3.  
  4. use Workerman\Worker; 
  5.  
  6. $worker = new Worker('text://0.0.0.0:6161'); 
  7.  
  8. $worker->onWorkerStart = function() { 
  9.  
  10.     global   $pull; 
  11.  
  12.     $loop    = Worker::getEventLoop(); 
  13.  
  14.     $context = new React\ZMQ\Context($loop); 
  15.  
  16.     $pull    = $context->getSocket(ZMQ::SOCKET_PULL); 
  17.  
  18.     $pull->bind('tcp://127.0.0.1:5555'); 
  19.  
  20.     $pull->on('error', function ($e) { 
  21.  
  22.         var_dump($e->getMessage()); 
  23.  
  24.     }); 
  25.  
  26.     $pull->on('message', function ($msg) { 
  27.  
  28.         echo "Received: $msg\n"; 
  29.  
  30.     }); 
  31.  
  32. }; 
  33.  
  34. Worker::runAll(); 

react的STOMP

composer require react/stomp

  1.  
  2. require_once __DIR__ . '/vendor/autoload.php'; 
  3.  
  4. use Workerman\Worker; 
  5.  
  6. $worker = new Worker('text://0.0.0.0:6161');  
  7.  
  8. $worker->onWorkerStart = function() { 
  9.  
  10.     global   $client; 
  11.  
  12.     $loop    = Worker::getEventLoop(); 
  13.  
  14.     $factory = new React\Stomp\Factory($loop); 
  15.  
  16.     $client  = $factory->createClient(array('vhost' => '/', 'login' => 'guest', 'passcode' => 'guest'));  
  17.  
  18.     $client 
  19.  
  20.         ->connect() 
  21.  
  22.         ->then(function ($client) use ($loop) { 
  23.  
  24.             $client->subscribe('/topic/foo', function ($frame) { 
  25.  
  26.                 echo "Message received: {$frame->body}\n"; 
  27.  
  28.             }); 
  29.  
  30.         }); 
  31.  
  32. }; 
  33.  
  34.  
  35.  
  36. Worker::runAll(); 

可用命令

php start.php start

php start.php start -d

e98162e9c0fdc68f6806079d39791cf.png

php start.php status [object Object]

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

代码:

  1.  
  2. use Workerman\Worker; 
  3.  
  4. $worker = new Worker('tcp://0.0.0.0:1234'); 
  5.  
  6. $worker->count=3; 
  7.  
  8. $worker->onMessage = function($connection, $data) 
  9.  
  10. { 
  11.  
  12.     $connection->send("HTTP/1.1 200 OK\r\nConnection: keep-alive\r\nServer: workerman\r\nContent-Length: 5\r\n\r\nhello"); 
  13.  
  14. }; 
  15.  
  16. Worker::runAll(); 

结果:

  1. ab -n1000000 -c100 -k http://127.0.0.1:1234/ 
  2.  
  3. This is ApacheBench, Version 2.3 <$Revision: 1528965 $> 
  4.  
  5. Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ 
  6.  
  7. Licensed to The Apache Software Foundation, http://www.apache.org/  
  8.  
  9. Benchmarking 127.0.0.1 (be patient) 
  10.  
  11. Completed 100000 requests 
  12.  
  13. Completed 200000 requests 
  14.  
  15. Completed 300000 requests 
  16.  
  17. Completed 400000 requests 
  18.  
  19. Completed 500000 requests 
  20.  
  21. Completed 600000 requests 
  22.  
  23. Completed 700000 requests 
  24.  
  25. Completed 800000 requests 
  26.  
  27. Completed 900000 requests 
  28.  
  29. Completed 1000000 requests 
  30.  
  31. Finished 1000000 requests   
  32.  
  33. Server Software:        workerman/3.1.4 
  34.  
  35. Server Hostname:        127.0.0.1 
  36.  
  37. Server Port:            1234 
  38.   
  39. Document Path:          / 
  40.  
  41. Document Length:        5 bytes  
  42.  
  43. Concurrency Level:      100 
  44.  
  45. Time taken for tests:   7.240 seconds 
  46.  
  47. Complete requests:      1000000 
  48.  
  49. Failed requests:        0 
  50.  
  51. Keep-Alive requests:    1000000 
  52.  
  53. Total transferred:      73000000 bytes 
  54.  
  55. HTML transferred:       5000000 bytes 
  56.  
  57. Requests per second:    138124.14 [#/sec] (mean) 
  58.  
  59. Time per request:       0.724 [ms] (mean) 
  60.  
  61. Time per request:       0.007 [ms] (mean, across all concurrent requests) 
  62.  
  63. Transfer rate:          9846.74 [Kbytes/sec] received 
  64.  
  65.  
  66. Connection Times (ms) 
  67.  
  68.               min  mean[+/-sd] median   max 
  69.  
  70. Connect:        0    0   0.0      0       5 
  71.  
  72. Processing:     0    1   0.2      1       9 
  73.  
  74. Waiting:        0    1   0.2      1       9 
  75.  
  76. Total:          0    1   0.2      1       9 
  77.   
  78. Percentage of the requests served within a certain time (ms) 
  79.  
  80.   50%      1 
  81.  
  82.   66%      1 
  83.  
  84.   75%      1 
  85.  
  86.   80%      1 
  87.  
  88.   90%      1 
  89.  
  90.   95%      1 
  91.  
  92.   98%      1 
  93.  
  94.   99%      1 
  95.  
  96.  100%      9 (longest request) 

本篇文章就是关于workerman的相关介绍,希望对需要的朋友有所帮助!workerman是什么?

Workerman是一个异步事件驱动的PHP框架,具有高性能,可轻松构建快速,可扩展的网络应用程序。支持HTTP,Websocket,SSL和其他自定义协议。支持libevent,HHVM,ReactPHP。

要求:

PHP 5.3或更高版本

兼容POSIX的操作系统(Linux,OSX,BSD)

用于PHP的POSIX和PCNTL扩展

安装:

composer require workerman/workerman

基本用法

websocket服务器

  1.  
  2. require_once __DIR__ . '/vendor/autoload.php'; 
  3.  
  4. use Workerman\Worker; 
  5.  
  6.  
  7. // 创建一个Websocket服务器 
  8.  
  9. $ws_worker = new Worker("websocket://0.0.0.0:2346"); 
  10.  
  11.  
  12. $ws_worker->count = 4; 
  13.  
  14.  
  15. // 在新连接到来时发出 
  16.  
  17. $ws_worker->onConnect = function($connection) 
  18.  
  19. { 
  20.  
  21.     echo "New connection\n"; 
  22.  
  23.  }; 
  24.  
  25.  
  26.  
  27. // 接收数据时发出 
  28.  
  29. $ws_worker->onMessage = function($connection, $data) 
  30.  
  31. { 
  32.  
  33.     // Send hello $data 
  34.  
  35.     $connection->send('hello ' . $data); 
  36.  
  37. }; 
  38.  
  39.  
  40.  
  41. // 连接关闭时发出 
  42.  
  43. $ws_worker->onClose = function($connection) 
  44.  
  45. { 
  46.  
  47.     echo "Connection closed\n"; 
  48.  
  49. }; 
  50.  
  51.  
  52. // 运行worker 
  53.  
  54. Worker::runAll(); 

http服务器

  1. require_once __DIR__ . '/vendor/autoload.php'; 
  2.  
  3. use Workerman\Worker; 
  4.  
  5.  
  6.  
  7. // #### http worker #### 
  8.  
  9. $http_worker = new Worker("http://0.0.0.0:2345"); 
  10.  
  11.  
  12.  
  13. $http_worker->count = 4; 
  14.  
  15.  
  16.  
  17. // 接收数据时发出 
  18.  
  19. $http_worker->onMessage = function($connection, $data) 
  20.  
  21. { 
  22.  
  23.     //$_GET、$_POST、$_COOKIE、$_SESSION、$_SERVER、$_FILES都是可用的 
  24.  
  25.     var_dump($_GET, $_POST, $_COOKIE, $_SESSION, $_SERVER, $_FILES); 
  26.  
  27.     // 发送数据给客户端 
  28.  
  29.     $connection->send("hello world \n"); 
  30.  
  31. }; 
  32.  
  33.  
  34. // 运行所有workers 
  35.  
  36. Worker::runAll(); 

WebServer

  1. require_once __DIR__ . '/vendor/autoload.php'; 
  2.  
  3. use Workerman\WebServer; 
  4.  
  5. use Workerman\Worker; 
  6.  
  7.  
  8.  
  9. // WebServer 
  10.  
  11. $web = new WebServer("http://0.0.0.0:80"); 
  12.  
  13.  
  14.  
  15. $web->count = 4; 
  16.  
  17.  
  18.  
  19. $web->addRoot('www.your_domain.com', '/your/path/Web'); 
  20.  
  21. $web->addRoot('www.another_domain.com', '/another/path/Web'); 
  22.  
  23.  
  24.  
  25. Worker::runAll(); 

TCP服务器

  1. require_once __DIR__ . '/vendor/autoload.php'; 
  2.  
  3. use Workerman\Worker; 
  4.  
  5.  
  6.  
  7. // #### 创建socket并监听1234端口 #### 
  8.  
  9. $tcp_worker = new Worker("tcp://0.0.0.0:1234"); 
  10.  
  11.  
  12.  
  13. $tcp_worker->count = 4; 
  14.  
  15.  
  16.  
  17. //在新连接到来时发出 
  18.  
  19. $tcp_worker->onConnect = function($connection) 
  20.  
  21. { 
  22.  
  23.     echo "New Connection\n"; 
  24.  
  25. }; 
  26.  
  27.  
  28.  
  29. // 接收数据时发出 
  30.  
  31. $tcp_worker->onMessage = function($connection, $data) 
  32.  
  33. { 
  34.  
  35.     // 发送数据给客户端 
  36.  
  37.     $connection->send("hello $data \n"); 
  38.  
  39. }; 
  40.  
  41.  
  42.  
  43. // 在新连接到来时发出 
  44.  
  45. $tcp_worker->onClose = function($connection) 
  46.  
  47. { 
  48.  
  49.     echo "Connection closed\n"; 
  50.  
  51. }; 
  52.  
  53.  
  54.  
  55. Worker::runAll(); 

启用SSL

  1. require_once __DIR__ . '/vendor/autoload.php'; 
  2.  
  3. use Workerman\Worker; 
  4.  
  5.  
  6.  
  7. // SSL环境 
  8.  
  9. $context = array( 
  10.  
  11.     'ssl' => array( 
  12.  
  13.         'local_cert'  => '/your/path/of/server.pem', 
  14.  
  15.         'local_pk'    => '/your/path/of/server.key', 
  16.  
  17.         'verify_peer' => false, 
  18.  
  19.     ) 
  20.  
  21. ); 
  22.  
  23.  
  24.  
  25. // 创建一个带有ssl的Websocket服务器。 
  26.  
  27. $ws_worker = new Worker("websocket://0.0.0.0:2346", $context); 
  28.  
  29.  
  30.  
  31. // 启用SSL。WebSocket+SSL意味着安全的WebSocket (wss://)。 
  32.  
  33. //类似的Https方法等等。 
  34.  
  35. $ws_worker->transport = 'ssl'; 
  36.  
  37.  
  38.  
  39. $ws_worker->onMessage = function($connection, $data) 
  40.  
  41. { 
  42.  
  43.     // 发送hello $data 
  44.  
  45.     $connection->send('hello ' . $data); 
  46.  
  47. }; 
  48.  
  49.  
  50.  
  51. Worker::runAll(); 

自定义协议

Protocols/MyTextProtocol.php

  1. namespace Protocols; 
  2.  
  3. /** 
  4.  
  5.  * 用户定义的协议 
  6.  
  7. *格式文本+“\ n” 
  8.  
  9.  */ 
  10.  
  11. class MyTextProtocol 
  12.  
  13. { 
  14.  
  15.     public static function input($recv_buffer) 
  16.  
  17.     { 
  18.  
  19.         // 找到“\n”第一个出现的位置 
  20.  
  21.         $pos = strpos($recv_buffer, "\n"); 
  22.  
  23.         // 不是一个完整的package。返回0,因为package的长度无法计算 
  24.  
  25.         if($pos === false) 
  26.  
  27.         { 
  28.  
  29.             return 0; 
  30.  
  31.         } 
  32.  
  33.         // 返回package的长度 
  34.  
  35.         return $pos+1; 
  36.  
  37.     } 
  38.  
  39.  
  40.  
  41.     public static function decode($recv_buffer) 
  42.  
  43.     { 
  44.  
  45.         return trim($recv_buffer); 
  46.  
  47.     } 
  48.  
  49.  
  50.  
  51.     public static function encode($data) 
  52.  
  53.     { 
  54.  
  55.         return $data."\n"; 
  56.  
  57.     } 
  58.  
  59. } 
  1. require_once __DIR__ . '/vendor/autoload.php'; 
  2.  
  3. use Workerman\Worker; 
  4.  
  5.  
  6.  
  7. // #### MyTextProtocol worker #### 
  8.  
  9. $text_worker = new Worker("MyTextProtocol://0.0.0.0:5678"); 
  10.  
  11.  
  12.  
  13. $text_worker->onConnect = function($connection) 
  14.  
  15. { 
  16.  
  17.     echo "New connection\n"; 
  18.  
  19. }; 
  20.  
  21.  
  22.  
  23. $text_worker->onMessage =  function($connection, $data) 
  24.  
  25. { 
  26.  
  27.     // 发送数据给客户端 
  28.  
  29.     $connection->send("hello world \n"); 
  30.  
  31. }; 
  32.  
  33.  
  34.  
  35. $text_worker->onClose = function($connection) 
  36.  
  37. { 
  38.  
  39.     echo "Connection closed\n"; 
  40.  
  41. }; 
  42.  
  43.  
  44.  
  45. // 运行所有workers 
  46.  
  47. Worker::runAll(); 

计时器

  1. require_once __DIR__ . '/vendor/autoload.php'; 
  2.  
  3. use Workerman\Worker; 
  4.  
  5. use Workerman\Lib\Timer; 
  6.  
  7.  
  8.  
  9. $task = new Worker(); 
  10.  
  11. $task->onWorkerStart = function($task) 
  12.  
  13. { 
  14.  
  15.     // 2.5秒 
  16.  
  17.     $time_interval = 2.5;  
  18.  
  19.     $timer_id = Timer::add($time_interval,  
  20.  
  21.         function() 
  22.  
  23.         { 
  24.  
  25.             echo "Timer run\n"; 
  26.  
  27.         } 
  28.  
  29.     ); 
  30.  
  31. }; 
  32.  
  33.  
  34.  
  35. //运行 
  36.  
  37. Worker::runAll(); 

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

  1. require_once __DIR__ . '/vendor/autoload.php'; 
  2.  
  3. use Workerman\Worker; 
  4.  
  5. use Workerman\Connection\AsyncTcpConnection; 
  6.  
  7.  
  8.  
  9. $worker = new Worker(); 
  10.  
  11. $worker->onWorkerStart = function() 
  12.  
  13. { 
  14.  
  15.     //客户端Websocket协议。 
  16.  
  17.     $ws_connection = new AsyncTcpConnection("ws://echo.websocket.org:80"); 
  18.  
  19.     $ws_connection->onConnect = function($connection){ 
  20.  
  21.         $connection->send('hello'); 
  22.  
  23.     }; 
  24.  
  25.     $ws_connection->onMessage = function($connection, $data){ 
  26.  
  27.         echo "recv: $data\n"; 
  28.  
  29.     }; 
  30.  
  31.     $ws_connection->onError = function($connection, $code, $msg){ 
  32.  
  33.         echo "error: $msg\n"; 
  34.  
  35.     }; 
  36.  
  37.     $ws_connection->onClose = function($connection){ 
  38.  
  39.         echo "connection closed\n"; 
  40.  
  41.     }; 
  42.  
  43.     $ws_connection->connect(); 
  44.  
  45. }; 
  46.  
  47. Worker::runAll(); 

ReactPHP的异步Mysql

composer require react/mysql

  1. require_once __DIR__ . '/vendor/autoload.php'; 
  2.  
  3. use Workerman\Worker; 
  4.  
  5.  
  6.  
  7. $worker = new Worker('tcp://0.0.0.0:6161'); 
  8.  
  9. $worker->onWorkerStart = function() { 
  10.  
  11.     global $mysql; 
  12.  
  13.     $loop  = Worker::getEventLoop(); 
  14.  
  15.     $mysql = new React\MySQL\Connection($loop, array( 
  16.  
  17.         'host'   => '127.0.0.1', 
  18.  
  19.         'dbname' => 'dbname', 
  20.  
  21.         'user'   => 'user', 
  22.  
  23.         'passwd' => 'passwd', 
  24.  
  25.     )); 
  26.  
  27.     $mysql->on('error', function($e){ 
  28.  
  29.         echo $e; 
  30.  
  31.     }); 
  32.  
  33.     $mysql->connect(function ($e) { 
  34.  
  35.         if($e) { 
  36.  
  37.             echo $e; 
  38.  
  39.         } else { 
  40.  
  41.             echo "connect success\n"; 
  42.  
  43.         } 
  44.  
  45.     }); 
  46.  
  47. }; 
  48.  
  49. $worker->onMessage = function($connection, $data) { 
  50.  
  51.     global $mysql; 
  52.  
  53.     $mysql->query('show databases' /*trim($data)*/, function ($command, $mysql) use ($connection) { 
  54.  
  55.         if ($command->hasError()) { 
  56.  
  57.             $error = $command->getError(); 
  58.  
  59.         } else { 
  60.  
  61.             $results = $command->resultRows; 
  62.  
  63.             $fields  = $command->resultFields; 
  64.  
  65.             $connection->send(json_encode($results)); 
  66.  
  67.         } 
  68.  
  69.     }); 
  70.  
  71. }; 
  72.  
  73. Worker::runAll(); 

ReactPHP的Async Redis

composer require clue/redis-react

  1. require_once __DIR__ . '/vendor/autoload.php'; 
  2.  
  3. use Clue\React\Redis\Factory; 
  4.  
  5. use Clue\React\Redis\Client; 
  6.  
  7. use Workerman\Worker; 
  8.  
  9.  
  10.  
  11. $worker = new Worker('tcp://0.0.0.0:6161'); 
  12.  
  13.  
  14.  
  15. $worker->onWorkerStart = function() { 
  16.  
  17.     global $factory; 
  18.  
  19.     $loop    = Worker::getEventLoop(); 
  20.  
  21.     $factory = new Factory($loop); 
  22.  
  23. }; 
  24.  
  25.  
  26.  
  27. $worker->onMessage = function($connection, $data) { 
  28.  
  29.     global $factory; 
  30.  
  31.     $factory->createClient('localhost:6379')->then(function (Client $client) use ($connection) { 
  32.  
  33.         $client->set('greeting', 'Hello world'); 
  34.  
  35.         $client->append('greeting', '!'); 
  36.  
  37.  
  38.  
  39.         $client->get('greeting')->then(function ($greeting) use ($connection){ 
  40.  
  41.             // Hello world! 
  42.  
  43.             echo $greeting . PHP_EOL; 
  44.  
  45.             $connection->send($greeting); 
  46.  
  47.         }); 
  48.  
  49.  
  50.  
  51.         $client->incr('invocation')->then(function ($n) use ($connection){ 
  52.  
  53.             echo 'This is invocation #' . $n . PHP_EOL; 
  54.  
  55.             $connection->send($n); 
  56.  
  57.         }); 
  58.  
  59.     }); 
  60.  
  61. }; 
  62.  
  63.  
  64.  
  65. Worker::runAll(); 

Aysnc dns的ReactPHP

composer require react/dns

  1. require_once __DIR__ . '/vendor/autoload.php'; 
  2.  
  3. use Workerman\Worker; 
  4.  
  5. $worker = new Worker('tcp://0.0.0.0:6161'); 
  6.  
  7. $worker->onWorkerStart = function() { 
  8.  
  9.     global   $dns; 
  10.  
  11.     // Get event-loop. 
  12.  
  13.     $loop    = Worker::getEventLoop(); 
  14.  
  15.     $factory = new React\Dns\Resolver\Factory(); 
  16.  
  17.     $dns     = $factory->create('8.8.8.8', $loop); 
  18.  
  19. }; 
  20.  
  21. $worker->onMessage = function($connection, $host) { 
  22.  
  23.     global $dns; 
  24.  
  25.     $host = trim($host); 
  26.  
  27.     $dns->resolve($host)->then(function($ip) use($host, $connection) { 
  28.  
  29.         $connection->send("$host: $ip"); 
  30.  
  31.     },function($e) use($host, $connection){ 
  32.  
  33.         $connection->send("$host: {$e->getMessage()}"); 
  34.  
  35.     }); 
  36.  
  37. }; 
  38.  
  39.  
  40.  
  41. Worker::runAll(); 

ReactPHP的Http客户端

composer require react/http-client

  1. require_once __DIR__ . '/vendor/autoload.php'; 
  2.  
  3. use Workerman\Worker; 
  4.  
  5.  
  6.  
  7. $worker = new Worker('tcp://0.0.0.0:6161'); 
  8.  
  9.  
  10.  
  11. $worker->onMessage = function($connection, $host) { 
  12.  
  13.     $loop    = Worker::getEventLoop(); 
  14.  
  15.     $client  = new \React\HttpClient\Client($loop); 
  16.  
  17.     $request = $client->request('GET', trim($host)); 
  18.  
  19.     $request->on('error', function(Exception $e) use ($connection) { 
  20.  
  21.         $connection->send($e); 
  22.  
  23.     }); 
  24.  
  25.     $request->on('response', function ($response) use ($connection) { 
  26.  
  27.         $response->on('data', function ($data) use ($connection) { 
  28.  
  29.             $connection->send($data); 
  30.  
  31.         }); 
  32.  
  33.     }); 
  34.  
  35.     $request->end(); 
  36.  
  37. }; 
  38.  
  39.  
  40.  
  41. Worker::runAll(); 

ReactPHP的ZMQ

composer require react/zmq

  1. require_once __DIR__ . '/vendor/autoload.php'; 
  2.  
  3. use Workerman\Worker; 
  4.  
  5. $worker = new Worker('text://0.0.0.0:6161'); 
  6.  
  7. $worker->onWorkerStart = function() { 
  8.  
  9.     global   $pull; 
  10.  
  11.     $loop    = Worker::getEventLoop(); 
  12.  
  13.     $context = new React\ZMQ\Context($loop); 
  14.  
  15.     $pull    = $context->getSocket(ZMQ::SOCKET_PULL); 
  16.  
  17.     $pull->bind('tcp://127.0.0.1:5555'); 
  18.  
  19.     $pull->on('error', function ($e) { 
  20.  
  21.         var_dump($e->getMessage()); 
  22.  
  23.     }); 
  24.  
  25.     $pull->on('message', function ($msg) { 
  26.  
  27.         echo "Received: $msg\n"; 
  28.  
  29.     }); 
  30.  
  31. }; 
  32.  
  33. Worker::runAll(); 

react的STOMP

composer require react/stomp

  1. require_once __DIR__ . '/vendor/autoload.php'; 
  2.  
  3. use Workerman\Worker; 
  4.  
  5.  
  6.  
  7. $worker = new Worker('text://0.0.0.0:6161'); 
  8.  
  9.  
  10.  
  11. $worker->onWorkerStart = function() { 
  12.  
  13.     global   $client; 
  14.  
  15.     $loop    = Worker::getEventLoop(); 
  16.  
  17.     $factory = new React\Stomp\Factory($loop); 
  18.  
  19.     $client  = $factory->createClient(array('vhost' => '/', 'login' => 'guest', 'passcode' => 'guest')); 
  20.  
  21.  
  22.  
  23.     $client 
  24.  
  25.         ->connect() 
  26.  
  27.         ->then(function ($client) use ($loop) { 
  28.  
  29.             $client->subscribe('/topic/foo', function ($frame) { 
  30.  
  31.                 echo "Message received: {$frame->body}\n"; 
  32.  
  33.             }); 
  34.  
  35.         }); 
  36.  
  37. }; 
  38.  
  39.  
  40.  
  41. Worker::runAll(); 

可用命令

php start.php start

php start.php start -d

e98162e9c0fdc68f6806079d39791cf.png

php start.php status [object Object]

php start.php connections

php start.php stop

php start.php restart

php start.php reload

基准

  1. CPU:      Intel(R) Core(TM) i3-3220 CPU @ 3.30GHz and 4 processors totally 
  2.  
  3. Memory:   8G 
  4.  
  5. OS:       Ubuntu 14.04 LTS 
  6.  
  7. Software: ab 

PHP: 5.5.9

代码:

  1. use Workerman\Worker; 
  2.  
  3. $worker = new Worker('tcp://0.0.0.0:1234'); 
  4.  
  5. $worker->count=3; 
  6.  
  7. $worker->onMessage = function($connection, $data) 
  8.  
  9. { 
  10.  
  11.     $connection->send("HTTP/1.1 200 OK\r\nConnection: keep-alive\r\nServer: workerman\r\nContent-Length: 5\r\n\r\nhello"); 
  12.  
  13. }; 
  14.  
  15. Worker::runAll(); 

结果

  1. ab -n1000000 -c100 -k http://127.0.0.1:1234/ 
  2.  
  3. This is ApacheBench, Version 2.3 <$Revision: 1528965 $> 
  4.  
  5. Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ 
  6.  
  7. Licensed to The Apache Software Foundation, http://www.apache.org/ 
  8.  
  9.  
  10.  
  11. Benchmarking 127.0.0.1 (be patient) 
  12.  
  13. Completed 100000 requests 
  14.  
  15. Completed 200000 requests 
  16.  
  17. Completed 300000 requests 
  18.  
  19. Completed 400000 requests 
  20.  
  21. Completed 500000 requests 
  22.  
  23. Completed 600000 requests 
  24.  
  25. Completed 700000 requests 
  26.  
  27. Completed 800000 requests 
  28.  
  29. Completed 900000 requests 
  30.  
  31. Completed 1000000 requests 
  32.  
  33. Finished 1000000 requests 
  34.  
  35.  
  36.  
  37.  
  38.  
  39. Server Software:        workerman/3.1.4 
  40.  
  41. Server Hostname:        127.0.0.1 
  42.  
  43. Server Port:            1234 
  44.  
  45.  
  46.  
  47. Document Path:          / 
  48.  
  49. Document Length:        5 bytes 
  50.  
  51.  
  52.  
  53. Concurrency Level:      100 
  54.  
  55. Time taken for tests:   7.240 seconds 
  56.  
  57. Complete requests:      1000000 
  58.  
  59. Failed requests:        0 
  60.  
  61. Keep-Alive requests:    1000000 
  62.  
  63. Total transferred:      73000000 bytes 
  64.  
  65. HTML transferred:       5000000 bytes 
  66.  
  67. Requests per second:    138124.14 [#/sec] (mean) 
  68.  
  69. Time per request:       0.724 [ms] (mean) 
  70.  
  71. Time per request:       0.007 [ms] (mean, across all concurrent requests) 
  72.  
  73. Transfer rate:          9846.74 [Kbytes/sec] received 
  74.  
  75.  
  76.  
  77. Connection Times (ms) 
  78.  
  79.               min  mean[+/-sd] median   max 
  80.  
  81. Connect:        0    0   0.0      0       5 
  82.  
  83. Processing:     0    1   0.2      1       9 
  84.  
  85. Waiting:        0    1   0.2      1       9 
  86.  
  87. Total:          0    1   0.2      1       9 
  88.  
  89.  
  90.  
  91. Percentage of the requests served within a certain time (ms) 
  92.  
  93.   50%      1 
  94.  
  95.   66%      1 
  96.  
  97.   75%      1 
  98.  
  99.   80%      1 
  100.  
  101.   90%      1 
  102.  
  103.   95%      1 
  104.  
  105.   98%      1 
  106.  
  107.   99%      1 
  108.  
  109.  100%      9 (longest request) 

本篇文章就是关于workerman的相关介绍,希望对需要的朋友有所帮助!

Tags: workerman基本用法

分享到: