workerman
GitHub | Stars | Last commit | Project created | Closed vsOpen issues |
---|---|---|---|---|
10493 | 2 weeks ago | 10 years ago | 510 / 58 |
Workerman
What is it
Workerman is an asynchronous event-driven PHP framework with high performance to build fast and scalable network applications. Workerman supports HTTP, Websocket, SSL and other custom protocols. Workerman supports event extension.
Requires
A POSIX compatible operating system (Linux, OSX, BSD)
POSIX and PCNTL extensions required
Event extension recommended for better performance
Installation
composer require workerman/workerman
Basic Usage
A websocket server
<?php
use Workerman\Worker;
require_once __DIR__ . '/vendor/autoload.php';
// Create a Websocket server
$ws_worker = new Worker('websocket://0.0.0.0:2346');
// 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
use Workerman\Worker;
require_once __DIR__ . '/vendor/autoload.php';
// #### 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, $request) {
//$request->get();
//$request->post();
//$request->header();
//$request->cookie();
//$request->session();
//$request->uri();
//$request->path();
//$request->method();
// Send data to client
$connection->send("Hello World");
};
// Run all workers
Worker::runAll();
A tcp server
use Workerman\Worker;
require_once __DIR__ . '/vendor/autoload.php';
// #### 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 connection is closed
$tcp_worker->onClose = function ($connection) {
echo "Connection closed\n";
};
Worker::runAll();
Enable SSL
<?php
use Workerman\Worker;
require_once __DIR__ . '/vendor/autoload.php';
// SSL context.
$context = [
'ssl' => [
'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";
}
}
use Workerman\Worker;
require_once __DIR__ . '/vendor/autoload.php';
// #### 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
use Workerman\Worker;
use Workerman\Timer;
require_once __DIR__ . '/vendor/autoload.php';
$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…)
use Workerman\Worker;
use Workerman\Connection\AsyncTcpConnection;
require_once __DIR__ . '/vendor/autoload.php';
$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();
Use HTTP proxy
<?php
require __DIR__ . '/vendor/autoload.php';
use Workerman\Connection\AsyncTcpConnection;
$worker = new \Workerman\Worker();
$worker->onWorkerStart = function($worker){
echo '开始链接' . PHP_EOL;
$url = 'ws://stream.binance.com:9443/ws';
$con = new AsyncTcpConnection($url);
$con->transport = 'ssl';
// $con->proxySocks5 = '127.0.0.1:1080';
$con->proxyHttp = '127.0.0.1:25378';
$con->onConnect = function(AsyncTcpConnection $con) {
$ww = [
'id' => 1,
'method' => 'SUBSCRIBE',
'params' => [
"btcusdt@aggTrade",
"btcusdt@depth"
]
];
echo '链接成功';
$con->send(json_encode($ww));
echo 'ok';
};
$con->onMessage = function(AsyncTcpConnection $con, $data) {
echo $data;
};
$con->onClose = function (AsyncTcpConnection $con) {
echo 'onClose' . PHP_EOL;
};
$con->onError = function (AsyncTcpConnection $con, $code, $msg) {
echo "error [ $code ] $msg\n";
};
$con->connect();
};
\Workerman\Worker::runAll();
Use Socks5 proxy
<?php
require __DIR__ . '/vendor/autoload.php';
use Workerman\Connection\AsyncTcpConnection;
$worker = new \Workerman\Worker();
$worker->onWorkerStart = function($worker){
echo '开始链接' . PHP_EOL;
$url = 'ws://stream.binance.com:9443/ws';
$con = new AsyncTcpConnection($url);
$con->transport = 'ssl';
$con->proxySocks5 = '127.0.0.1:1080';
// $con->proxyHttp = '127.0.0.1:25378';
$con->onConnect = function(AsyncTcpConnection $con) {
$ww = [
'id' => 1,
'method' => 'SUBSCRIBE',
'params' => [
"btcusdt@aggTrade",
"btcusdt@depth"
]
];
echo '链接成功';
$con->send(json_encode($ww));
echo 'ok';
};
$con->onMessage = function(AsyncTcpConnection $con, $data) {
echo $data;
};
$con->onClose = function (AsyncTcpConnection $con) {
echo 'onClose' . PHP_EOL;
};
$con->onError = function (AsyncTcpConnection $con, $code, $msg) {
echo "error [ $code ] $msg\n";
};
$con->connect();
};
\Workerman\Worker::runAll();
proxy supports TLS1.3, no Sniproxy channel
Available commands
php start.php start
php start.php start -d
php start.php status
php start.php status -d
php start.php connections
php start.php stop
php start.php stop -g
php start.php restart
php start.php reload
php start.php reload -g
Documentation
中文主页: http://www.workerman.net
中文文档: http://doc.workerman.net
Documentation: https://github.com/walkor/workerman-manual
Benchmarks
https://www.techempower.com/benchmarks/#section=data-r19&hw=ph&test=plaintext&l=zik073-1r
Other links with workerman
Donate
LICENSE
Workerman is released under the MIT license.