workerman是什么?
Workerman是一个异步事件驱动的PHP框架,具有高性能,可轻松构建快速,可扩展的网络应用程序。支持HTTP,Websocket,SSL和其他自定义协议。支持libevent,HHVM,ReactPHP。八重樱:腾讯T3-T4标准精品PHP架构师教程目录大全,只要你看完保证薪资上升一个台阶(持续更新)zhuanlan.zhihu.com
要求PHP 5.3或更高版本
兼容POSIX的操作系统(Linux,OSX,BSD)
用于PHP的POSIX和PCNTL扩展
安装
composer require workerman/workerman
基本用法
websocket服务器
require_once __DIR__ . '/vendor/autoload.php';
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('hello ' . $data);
};
// 连接关闭时发出
$ws_worker->onClose = function($connection)
{
echo "Connection closed\n";
};
// 运行worker
Worker::runAll();
http服务器
require_once __DIR__ . '/vendor/autoload.php';
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__ . '/vendor/autoload.php';
use Workerman\WebServer;
use Workerman\Worker;
// WebServer
$web = new WebServer("http://0.0.0.0:80");
$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;
// #### 创建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
require_once __DIR__ . '/vendor/autoload.php';
use Workerman\Worker;
// SSL环境
$context = array(
'ssl' => array(
'local_cert' => '/your/path/of/server.pem',
'local_pk' => '/your/path/of/server.key',
'verify_peer' => false,
)
);
// 创建一个带有ssl的Websocket服务器。
$ws_worker = new Worker("websocket://0.0.0.0:2346", $context);
// 启用SSL。WebSocket+SSL意味着安全的WebSocket (wss://)。
//类似的Https方法等等。
$ws_worker->transport = 'ssl';
$ws_worker->onMessage = function($connection, $data)
{
// 发送hello $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");
// 不是一个完整的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__ . '/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)
{
// 发送数据给客户端
$connection->send("hello world \n");
};
$text_worker->onClose = function($connection)
{
echo "Connection closed\n";
};
// 运行所有workers
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 "Timer run\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('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();
ReactPHP的异步Mysql
composer require react/mysql
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();
ReactPHP的Async Redis
composer require clue/redis-react
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的ReactPHP
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();
ReactPHP的Http客户端
composer require react/http-client
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();
ReactPHP的ZMQ
composer require react/zmq
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();
react的STOMP
composer requirereact/stomp
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();
可用命令
php start.php start
php start.php start -d
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
代码
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
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的基本用法(示例详解)的详细内容
以上内容希望帮助到大家,很多PHPer在进阶的时候总会遇到一些问题和瓶颈,业务代码写多了没有方向感,不知道该从那里入手去提升,对此我整理了一些资料,包括但不限于:分布式架构、高可扩展、高性能、高并发、服务器性能调优、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx等多个知识点高级进阶干货需要的可以免费分享给大家,需要的可以加入我的官方群点击此处。
更多知识点八重樱:腾讯T3-T4标准精品PHP架构师教程目录大全,只要你看完保证薪资上升一个台阶(持续更新)zhuanlan.zhihu.com
参考^内容不错的话希望大家支持鼓励下点个赞/喜欢,欢迎一起来交流;另外如果有什么问题和想看的内容可以在评论提出