생성자 __construct
설명:
Worker::__construct([string $listen , array $context])
Worker 컨테이너 인스턴스를 초기화하며, 컨테이너의 일부 속성과 콜백 인터페이스를 설정하여 특정 기능을 완료합니다.
매개변수
$listen (선택적 매개변수, 입력하지 않으면 어떤 포트도 수신하지 않음)
$listen 매개변수가 설정된 경우, 소켓 수신이 수행됩니다.
$listen의 형식은 <프로토콜>://<수신 주소>입니다.
<프로토콜>은 다음 형식 중 하나일 수 있습니다:
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 내장 텍스트 프로토콜이며, telnet과 호환됨. 자세한 내용은 부록 텍스트 프로토콜 부분을 참조)
기타 사용자 정의 프로토콜은 본 매뉴얼의 사용자 정의 통신 프로토콜 섹션을 참조하십시오.
<수신 주소>는 다음 형식 중 하나일 수 있습니다:
unix 소켓인 경우, 주소는 로컬의 디스크 경로입니다.
비유닉스 소켓인 경우, 주소 형식은 <로컬 IP>:<포트 번호>입니다.
<로컬 IP>는 0.0.0.0으로 설정하면 로컬의 모든 네트워크 인터페이스를 수신하며, 내외부 IP 및 로컬 루프백 127.0.0.1을 포함합니다.
<로컬 IP>가 127.0.0.1이면 로컬 루프백을 수신하며, 로컬에서만 접근 가능하고 외부에서는 접근할 수 없습니다.
<로컬 IP>가 사설 IP인 경우, 예를 들어 192.168.xx.xx이면 내부 IP만 수신하며 외부 사용자 접근 불가합니다.
<로컬 IP>에 설정된 값이 로컬 IP와 일치하지 않으면 수신을 실행할 수 없으며, Cannot assign requested address 오류가 발생합니다.
주의: <포트 번호>는 65535를 초과할 수 없습니다. <포트 번호>가 1024보다 작으면 root 권한이 필요합니다. 수신하려는 포트는 로컬에서 사용 중이 아닌 포트여야 하며, 그렇지 않으면 Address already in use 오류가 발생합니다.
$context
소켓의 컨텍스트 옵션을 전달하기 위한 배열입니다. 소켓 컨텍스트 옵션을 참조하십시오.
예제
Worker가 http 컨테이너로서 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::runAll();
Worker가 websocket 컨테이너로서 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::runAll();
Worker가 tcp 컨테이너로서 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::runAll();
Worker가 udp 컨테이너로서 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::runAll();
Worker가 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::runAll();
아무것도 수신하지 않는 Worker 컨테이너로, 일부 정기 작업을 처리하는 용도로 사용됩니다.
use \Workerman\Worker;
use \Workerman\Timer;
require_once __DIR__ . '/vendor/autoload.php';
$task = new Worker();
$task->onWorkerStart = function($task)
{
// 2.5초마다 실행
$time_interval = 2.5;
Timer::add($time_interval, function()
{
echo "task run\n";
});
};
// 워커 실행
Worker::runAll();
Worker가 사용자 정의 프로토콜의 포트를 수신합니다.
최종 디렉토리 구조
├── Protocols // 생성할 Protocols 디렉토리
│ └── MyTextProtocol.php // 생성할 사용자 정의 프로토콜 파일
├── test.php // 생성할 test 스크립트
└── Workerman // Workerman 소스 디렉토리, 내부 코드는 수정하지 마십시오.
1、Protocols 디렉토리를 생성하고 프로토콜 파일을 생성합니다.
Protocols/MyTextProtocol.php(위 디렉토리 구조 참조)
// 사용자 정의 프로토콜 네임스페이스는 'Protocols'로 통일
namespace Protocols;
// 간단한 텍스트 프로토콜, 프로토콜 형식은 텍스트 + 개행
class MyTextProtocol
{
// 패킷 분할 기능, 현재 패킷의 길이를 반환
public static function input($recv_buffer)
{
// 개행 문자 찾기
$pos = strpos($recv_buffer, "\n");
// 개행 문자를 찾지 못했으면, 전체 패킷이 아닙니다 - 0 반환하고 데이터 대기
if($pos === false)
{
return 0;
}
// 개행 문자를 찾았으면, 현재 패킷의 길이(개행 문자를 포함하여) 반환
return $pos+1;
}
// 완전한 패킷을 수신한 후, decode를 통해 자동으로 디코딩됩니다. 여기서는 개행 문자를 트림합니다.
public static function decode($recv_buffer)
{
return trim($recv_buffer);
}
// 클라이언트에 데이터를 보내기 전에 자동으로 encode를 통해 인코딩된 후 전송됩니다. 여기서는 개행 문자를 추가합니다.
public static function encode($data)
{
return $data."\n";
}
}
2、MyTextProtocol 프로토콜을 사용하여 요청을 수신 처리합니다.
최종 디렉토리 구조를 참조하여 test.php 파일을 만듭니다.
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';
// #### MyTextProtocol 워커 ####
$text_worker = new Worker("MyTextProtocol://0.0.0.0:5678");
/*
* 개행 문자로 끝나는 완전한 데이터를 수신한 후, 자동으로 MyTextProtocol::decode('받은 데이터')를 실행합니다.
* 결과는 $data를 통해 onMessage 콜백으로 전달됩니다.
*/
$text_worker->onMessage = function(TcpConnection $connection, $data)
{
var_dump($data);
/*
* 클라이언트에 데이터를 보내면 자동으로 MyTextProtocol::encode('hello world')를 통해 프로토콜 인코딩이 되며,
* 그 후 클라이언트로 전송됩니다.
*/
$connection->send("hello world");
};
// 모든 워커 실행
Worker::runAll();
3、테스트
터미널을 열고, test.php가 있는 디렉토리로 이동한 후 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을 이용해 테스트합니다. (리눅스 시스템의 telnet 사용을 권장)
로컬 테스트를 가정하고,
터미널에서 telnet 127.0.0.1 5678를 실행합니다.
그런 다음 hi를 입력하고 엔터를 누릅니다.
데이터 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