全部
常见问题
产品动态
精选推荐

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服务器


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

2f960202310071039557166.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

代码


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的基本用法(示例详解)的详细内容


请登录后查看

CRMEB-慕白寒窗雪 最后编辑于2023-10-07 10:40:43

快捷回复
回复
回复
回复({{post_count}}) {{!is_user ? '我的回复' :'全部回复'}}
排序 默认正序 回复倒序 点赞倒序

{{item.user_info.nickname ? item.user_info.nickname : item.user_name}} LV.{{ item.user_info.bbs_level }}

作者 管理员 企业

{{item.floor}}# 同步到gitee 已同步到gitee {{item.is_suggest == 1? '取消推荐': '推荐'}}
{{item.is_suggest == 1? '取消推荐': '推荐'}}
沙发 板凳 地板 {{item.floor}}#
{{item.user_info.title || '暂无简介'}}
附件

{{itemf.name}}

{{item.created_at}}  {{item.ip_address}}
{{item.like_count}}
{{item.showReply ? '取消回复' : '回复'}}
删除
回复
回复

{{itemc.user_info.nickname}}

{{itemc.user_name}}

回复 {{itemc.comment_user_info.nickname}}

附件

{{itemf.name}}

{{itemc.created_at}}
{{itemc.like_count}}
{{itemc.showReply ? '取消回复' : '回复'}}
删除
回复
回复
查看更多
1612
{{like_count}}
{{collect_count}}
添加回复 ({{post_count}})

快速安全登录

使用微信扫码登录
{{item.label}} 加精
{{item.label}} {{item.label}} 板块推荐 常见问题 产品动态 精选推荐 首页头条 首页动态 首页推荐
取 消 确 定
回复
回复
问题:
问题自动获取的帖子内容,不准确时需要手动修改. [获取答案]
答案:
提交
bug 需求 取 消 确 定

微信登录/注册

切换手机号登录

{{ bind_phone ? '绑定手机' : '手机登录'}}

{{codeText}}
切换微信登录/注册
暂不绑定
CRMEB客服

CRMEB咨询热线 咨询热线

400-8888-794

微信扫码咨询

CRMEB开源商城下载 源码下载 CRMEB帮助文档 帮助文档
返回顶部 返回顶部
CRMEB客服