構(gòu)造函數(shù) __construct
說明:
Worker::__construct([string $listen , array $context])
初始化一個Worker容器實例,可以設(shè)置容器的一些屬性和回調(diào)接口,完成特定功能。
參數(shù)
$listen
(可選參數(shù),不填寫表示不監(jiān)聽任何端口)
如果有設(shè)置監(jiān)聽$listen
參數(shù),則會執(zhí)行socket監(jiān)聽。
$listen 的格式為 <協(xié)議>://<監(jiān)聽地址>
<協(xié)議> 可以為以下格式:
tcp: 例如 tcp://0.0.0.0:8686
udp: 例如 udp://0.0.0.0:8686
unix: 例如 unix:///tmp/my_file
(需要Workerman>=3.2.7)
http: 例如 http://0.0.0.0:80
websocket: 例如 websocket://0.0.0.0:8686
text: 例如 text://0.0.0.0:8686
(text是Workerman內(nèi)置的文本協(xié)議,兼容telnet,詳情參見附錄Text協(xié)議部分)
以及其他自定義協(xié)議,參見本手冊定制通訊協(xié)議部分
<監(jiān)聽地址> 可以為以下格式:
如果是unix套接字,地址為本地一個磁盤路徑
非unix套接字,地址格式為 <本機ip>:<端口號>
<本機ip>可以為0.0.0.0
表示監(jiān)聽本機所有網(wǎng)卡,包括內(nèi)網(wǎng)ip和外網(wǎng)ip及本地回環(huán)127.0.0.1
<本機ip>如果以為127.0.0.1
表示監(jiān)聽本地回環(huán),只能本機訪問,外部無法訪問
<本機ip>如果為內(nèi)網(wǎng)ip,類似192.168.xx.xx
,表示只監(jiān)聽內(nèi)網(wǎng)ip,則外網(wǎng)用戶無法訪問
<本機ip>設(shè)置的值不屬于本機ip則無法執(zhí)行監(jiān)聽,并且提示Cannot assign requested address
錯誤
注意:<端口號>不能大于65535。<端口號>如果小于1024則需要root權(quán)限才能監(jiān)聽。監(jiān)聽的端口必須是本機未被占用的端口,否則無法監(jiān)聽,并且提示Address already in use
錯誤
$context
一個數(shù)組。用于傳遞socket的上下文選項,參見套接字上下文選項
范例
Worker作為http容器監(jiān)聽處理http請求
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
use Workerman\Protocols\Http\Request;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker('http://0.0.0.0:8686');
$worker->onMessage = function(TcpConnection $connection, Request $request)
{
$connection->send("hello");
};
// 運行worker
Worker::runAll();
Worker作為websocket容器監(jiān)聽處理websocket請求
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker('websocket://0.0.0.0:8686');
$worker->onMessage = function(TcpConnection $connection, $data)
{
$connection->send("hello");
};
// 運行worker
Worker::runAll();
Worker作為tcp容器監(jiān)聽處理tcp請求
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker('tcp://0.0.0.0:8686');
$worker->onMessage = function(TcpConnection $connection, $data)
{
$connection->send("hello");
};
// 運行worker
Worker::runAll();
Worker作為udp容器監(jiān)聽處理udp請求
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker('udp://0.0.0.0:8686');
$worker->onMessage = function(TcpConnection $connection, $data)
{
$connection->send("hello");
};
// 運行worker
Worker::runAll();
Worker監(jiān)聽unix domain套接字(要求Workerman版本>=3.2.7)
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker('unix:///tmp/my.sock');
$worker->onMessage = function(TcpConnection $connection, $data)
{
$connection->send("hello");
};
// 運行worker
Worker::runAll();
不執(zhí)行任何監(jiān)聽的Worker容器,用來處理一些定時任務(wù)
use \Workerman\Worker;
use \Workerman\Timer;
require_once __DIR__ . '/vendor/autoload.php';
$task = new Worker();
$task->onWorkerStart = function($task)
{
// 每2.5秒執(zhí)行一次
$time_interval = 2.5;
Timer::add($time_interval, function()
{
echo "task run\n";
});
};
// 運行worker
Worker::runAll();
Worker監(jiān)聽自定義協(xié)議的端口
最終的目錄結(jié)構(gòu)
├── Protocols // 這是要創(chuàng)建的Protocols目錄
│?? └── MyTextProtocol.php // 這是要創(chuàng)建的自定義協(xié)議文件
├── test.php // 這是要創(chuàng)建的test腳本
└── Workerman // Workerman源碼目錄,里面代碼不要動
1、創(chuàng)建Protocols目錄,并創(chuàng)建一個協(xié)議文件
Protocols/MyTextProtocol.php(參照上面目錄結(jié)構(gòu))
// 用戶自定義協(xié)議命名空間統(tǒng)一為Protocols
namespace Protocols;
//簡單文本協(xié)議,協(xié)議格式為 文本+換行
class MyTextProtocol
{
// 分包功能,返回當前包的長度
public static function input($recv_buffer)
{
// 查找換行符
$pos = strpos($recv_buffer, "\n");
// 沒找到換行符,表示不是一個完整的包,返回0繼續(xù)等待數(shù)據(jù)
if($pos === false)
{
return 0;
}
// 查找到換行符,返回當前包的長度,包括換行符
return $pos+1;
}
// 收到一個完整的包后通過decode自動解碼,這里只是把換行符trim掉
public static function decode($recv_buffer)
{
return trim($recv_buffer);
}
// 給客戶端send數(shù)據(jù)前會自動通過encode編碼,然后再發(fā)送給客戶端,這里加了換行
public static function encode($data)
{
return $data."\n";
}
}
2、使用MyTextProtocol協(xié)議監(jiān)聽處理請求
參照上面最終目錄結(jié)構(gòu)創(chuàng)建test.php文件
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';
// #### MyTextProtocol worker ####
$text_worker = new Worker("MyTextProtocol://0.0.0.0:5678");
/*
* 收到一個完整的數(shù)據(jù)(結(jié)尾是換行)后,自動執(zhí)行MyTextProtocol::decode('收到的數(shù)據(jù)')
* 結(jié)果通過$data傳遞給onMessage回調(diào)
*/
$text_worker->onMessage = function(TcpConnection $connection, $data)
{
var_dump($data);
/*
* 給客戶端發(fā)送數(shù)據(jù),會自動調(diào)用MyTextProtocol::encode('hello world')進行協(xié)議編碼,
* 然后再發(fā)送到客戶端
*/
$connection->send("hello world");
};
// run all workers
Worker::runAll();
3、測試
打開終端,進入到test.php所在目錄,執(zhí)行php test.php start
php test.php start
Workerman[test.php] start in DEBUG mode
----------------------- WORKERMAN -----------------------------
Workerman version:3.2.7 PHP version:5.4.37
------------------------ WORKERS -------------------------------
user worker listen processes status
root none myTextProtocol://0.0.0.0:5678 1 [OK]
----------------------------------------------------------------
Press Ctrl-C to quit. Start success.
打開終端,利用telnet測試(建議用linux系統(tǒng)的telnet)
假設(shè)是本機測試,
終端執(zhí)行 telnet 127.0.0.1 5678
然后輸入 hi回車
會接收到數(shù)據(jù)hello world\n
telnet 127.0.0.1 5678
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
hi
hello world