php reactphp wss_Workerman: Workerman是一款纯PHP开发的开源高性能的PHP socket 服务器框架。被广泛的用于手机app、移动通讯,微信小程序,手游服务端、网...

Workerman是一个强大的PHP socket服务器框架,支持HTTP、Websocket、SSL等多种协议。本文展示了如何创建Websocket、HTTP、TCP服务器,并演示了启用SSL和自定义协议的方法。此外,还提到了Workerman与其他ReactPHP组件如AsyncTcpConnection、AsyncMysql、AsyncRedis等的结合使用,以及其高并发性能基准测试。
摘要由CSDN通过智能技术生成

Workerman

What is it

Workerman is an asynchronous event driven PHP framework with high performance for easily building fast, scalable network applications. Supports HTTP, Websocket, SSL and other custom protocols. Supports libevent, HHVM , ReactPHP.

Requires

PHP 5.3 or Higher

A POSIX compatible operating system (Linux, OSX, BSD)

POSIX and PCNTL extensions for PHP

Installation

composer require workerman/workerman

Basic Usage

A websocket server

require_once __DIR__ . '/vendor/autoload.php';

use Workerman\Worker;

// Create a Websocket server

$ws_worker = new Worker("websocket://0.0.0.0:2346");

// 4 processes

$ws_worker->count = 4;

// Emitted when new connection come

$ws_worker->onConnect = function($connection)

{

echo "New connection\n";

};

// Emitted when data received

$ws_worker->onMessage = function($connection, $data)

{

// Send hello $data

$connection->send('hello ' . $data);

};

// Emitted when connection closed

$ws_worker->onClose = function($connection)

{

echo "Connection closed\n";

};

// Run worker

Worker::runAll();

An http server

require_once __DIR__ . '/vendor/autoload.php';

use Workerman\Worker;

// #### http worker ####

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

// 4 processes

$http_worker->count = 4;

// Emitted when data received

$http_worker->onMessage = function($connection, $data)

{

// $_GET, $_POST, $_COOKIE, $_SESSION, $_SERVER, $_FILES are available

var_dump($_GET, $_POST, $_COOKIE, $_SESSION, $_SERVER, $_FILES);

// send data to client

$connection->send("hello world\n");

};

// run all workers

Worker::runAll();

A WebServer

require_once __DIR__ . '/vendor/autoload.php';

use Workerman\WebServer;

use Workerman\Worker;

// WebServer

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

// 4 processes

$web->count = 4;

// Set the root of domains

$web->addRoot('www.your_domain.com', '/your/path/Web');

$web->addRoot('www.another_domain.com', '/another/path/Web');

// run all workers

Worker::runAll();

A tcp server

require_once __DIR__ . '/vendor/autoload.php';

use Workerman\Worker;

// #### create socket and listen 1234 port ####

$tcp_worker = new Worker("tcp://0.0.0.0:1234");

// 4 processes

$tcp_worker->count = 4;

// Emitted when new connection come

$tcp_worker->onConnect = function($connection)

{

echo "New Connection\n";

};

// Emitted when data received

$tcp_worker->onMessage = function($connection, $data)

{

// send data to client

$connection->send("hello$data\n");

};

// Emitted when new connection come

$tcp_worker->onClose = function($connection)

{

echo "Connection closed\n";

};

Worker::runAll();

Enable SSL

require_once __DIR__ . '/vendor/autoload.php';

use Workerman\Worker;

// SSL context.

$context = array(

'ssl' => array(

'local_cert' => '/your/path/of/server.pem',

'local_pk' => '/your/path/of/server.key',

'verify_peer' => false,

)

);

// Create a Websocket server with ssl context.

$ws_worker = new Worker("websocket://0.0.0.0:2346", $context);

// Enable SSL. WebSocket+SSL means that Secure WebSocket (wss://).

// The similar approaches for Https etc.

$ws_worker->transport = 'ssl';

$ws_worker->onMessage = function($connection, $data)

{

// Send hello $data

$connection->send('hello ' . $data);

};

Worker::runAll();

Custom protocol

Protocols/MyTextProtocol.php

namespace Protocols;

/**

* User defined protocol

* Format Text+"\n"

*/

class MyTextProtocol

{

public static function input($recv_buffer)

{

// Find the position of the first occurrence of "\n"

$pos = strpos($recv_buffer, "\n");

// Not a complete package. Return 0 because the length of package can not be calculated

if($pos === false)

{

return 0;

}

// Return length of the 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)

{

// send data to client

$connection->send("hello world\n");

};

$text_worker->onClose = function($connection)

{

echo "Connection closed\n";

};

// run all workers

Worker::runAll();

Timer

require_once __DIR__ . '/vendor/autoload.php';

use Workerman\Worker;

use Workerman\Lib\Timer;

$task = new Worker();

$task->onWorkerStart = function($task)

{

// 2.5 seconds

$time_interval = 2.5;

$timer_id = Timer::add($time_interval,

function()

{

echo "Timer run\n";

}

);

};

// run all workers

Worker::runAll();

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

require_once __DIR__ . '/vendor/autoload.php';

use Workerman\Worker;

use Workerman\Connection\AsyncTcpConnection;

$worker = new Worker();

$worker->onWorkerStart = function()

{

// Websocket protocol for client.

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

Async Mysql of ReactPHP

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

Async Redis of ReactPHP

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

Http client of ReactPHP

composer require react/http-client

require_once __DIR__ . '/vendor/autoload.php';

use Workerman\Worker;

$worker = new Worker('tcp://0.0.0.0:6161');

$worker->onWorkerStart = function() {

global $client;

$loop = Worker::getEventLoop();

$factory = new React\Dns\Resolver\Factory();

$dns = $factory->createCached('8.8.8.8', $loop);

$factory = new React\HttpClient\Factory();

$client = $factory->create($loop, $dns);

};

$worker->onMessage = function($connection, $host) {

global $client;

$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, $response) use ($connection) {

$connection->send($data);

});

});

$request->end();

};

Worker::runAll();

ZMQ of ReactPHP

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

STOMP of ReactPHP

composer require react/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();

Available commands

php start.php start

php start.php start -d

php start.php status

php start.php connections

php start.php stop

php start.php restart

php start.php reload

Documentation

Benchmarks

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

Codes

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

Result

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 fortests: 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)

Other links with workerman

Donate

LICENSE

Workerman is released under the MIT license.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值