workman php教程_workerman的基本用法(示例详解)

f2f9174cd6cbca5baa8ec4c87c2ce558.png

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

要求PHP 5.3或更高版本

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

用于PHP的POSIX和PCNTL扩展

安装composer require workerman/workerman

基本用法

websocket服务器<?php

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();

WebServerrequire_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<?php

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.phpnamespace 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的异步Mysqlcomposer require react/mysql<?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();

ReactPHP的Async Rediscomposer 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;

$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的ReactPHPcomposer require react/dnsrequire_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<?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();

ReactPHP的ZMQcomposer 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();

react的STOMPcomposer 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();

可用命令php start.php start

php start.php start -d

bfe0b2269c6becf3f8570840d71264a6.pngphp 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

代码<?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

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的相关介绍,希望对需要的朋友有所帮助!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Workerman中,可以通过使用异步任务来处理长连接中的业务逻辑,避免阻塞主进程。异步任务可以在Worker进程中通过`AsyncTask`类来实现,具体的步骤如下: 1. 在Worker进程中创建`AsyncTask`对象,指定异步任务的处理方法。 ```php use \Workerman\Worker; use \Workerman\MySQL\Connection; use \Workerman\AsyncTask; $worker = new Worker('tcp://0.0.0.0:8000'); $worker->onWorkerStart = function($worker) { // 创建MySQL连接 $mysql = new Connection('127.0.0.1', '3306', 'username', 'password', 'dbname'); // 创建异步任务 $task = new AsyncTask(); // 设置异步任务的处理方法 $task->onMessage = function($task, $data) use ($mysql) { // 处理业务逻辑 $result = $mysql->query('SELECT * FROM users WHERE id='.$data); // 返回处理结果 $task->send($result); }; // 将异步任务注册到Worker进程中 $worker->addTask($task); }; ``` 2. 在客户端连接上来后,将需要处理的数据发送到异步任务中,等待异步任务处理完成后,再将结果返回给客户端。 ```php $worker->onConnect = function($connection) use ($worker) { // 接收客户端发送的数据 $connection->onMessage = function($connection, $data) use ($worker) { // 将数据发送到异步任务中处理 $worker->task($data, function($result) use ($connection) { // 处理异步任务返回的结果 $connection->send(json_encode($result)); }); }; }; ``` 通过以上的步骤,我们就可以在长连接中使用异步任务来处理业务逻辑了。需要注意的是,异步任务的处理方法会在Worker进程中的异步任务进程中执行,所以需要将需要的资源例如MySQL连接等在onWorkerStart回调函数中创建。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值