Construtor __construct
Descrição:
Worker::__construct([string $listen , array $context])
Inicializa uma instância do Worker container, permitindo configurar algumas propriedades e interfaces de callback do container, para concluir funcionalidades específicas.
Parâmetros
$listen (parâmetro opcional, não preenchido significa que não está escutando em nenhuma porta)
Se o parâmetro de escuta $listen estiver definido, será executada a escuta via socket.
O formato de $listen é ://<endereço de escuta>
pode ser um dos seguintes formatos:
tcp: por exemplo tcp://0.0.0.0:8686
udp: por exemplo udp://0.0.0.0:8686
unix: por exemplo unix:///tmp/my_file (requer Workerman>=3.2.7)
http: por exemplo http://0.0.0.0:80
websocket: por exemplo websocket://0.0.0.0:8686
text: por exemplo text://0.0.0.0:8686 (text é o protocolo de texto embutido no Workerman, compatível com telnet, veja detalhes na seção do Apêndice sobre o Protocolo Text)
e outros protocolos personalizados, consulte a seção do manual sobre a personalização de protocolos de comunicação.
<endereço de escuta> pode ser um dos seguintes formatos:
Se for um socket unix, o endereço deve ser um caminho de disco local.
Para sockets não-unix, o formato do endereço é :<número da porta>.
pode ser ```0.0.0.0``` para escutar em todos os adaptadores de rede da máquina, incluindo ip local e ip externo, assim como o loopback local 127.0.0.1.
Se for ```127.0.0.1```, a escuta será apenas no loopback local, acessível somente a partir da máquina, e não externamente.
Se for um ip local, como ```192.168.xx.xx```, a escuta será apenas nesse ip local, tornando inacessível para usuários externos.
Se o valor de não pertencer aos ips da máquina, a escuta não será possível, resultando no erro ```Cannot assign requested address```.
**Nota:** não pode ser maior que 65535. Se for menor que 1024, será necessário ter privilégios de root para escutar. A porta de escuta deve estar livre na máquina, caso contrário, resultará no erro ```Address already in use```.
#### **``` $context ```**
Um array. Usado para passar opções de contexto do socket, consulte [opções de contexto de socket](https://php.net/manual/pt/context.socket.php).
## Exemplos
Worker atuando como um container http escutando e processando requisições http
```php
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");
};
// Executa o worker
Worker::runAll();
```
Worker atuando como um container websocket escutando e processando requisições websocket
```php
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");
};
// Executa o worker
Worker::runAll();
```
Worker atuando como um container tcp escutando e processando requisições tcp
```php
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");
};
// Executa o worker
Worker::runAll();
```
Worker atuando como um container udp escutando e processando requisições udp
```php
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");
};
// Executa o worker
Worker::runAll();
```
Worker escutando socket de domínio unix ```(requer Workerman versão>=3.2.7)```
```php
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");
};
// Executa o worker
Worker::runAll();
```
Worker sem qualquer escuta, utilizado para processar algumas tarefas agendadas
```php
use \Workerman\Worker;
use \Workerman\Timer;
require_once __DIR__ . '/vendor/autoload.php';
$task = new Worker();
$task->onWorkerStart = function($task)
{
// Executa a cada 2,5 segundos
$time_interval = 2.5;
Timer::add($time_interval, function()
{
echo "task run\n";
});
};
// Executa o worker
Worker::runAll();
```
**Worker escutando a porta de protocolo personalizado**
Estrutura final do diretório
```
├── Protocols // Este é o diretório Protocols que deve ser criado
│ └── MyTextProtocol.php // Este é o arquivo de protocolo personalizado que deve ser criado
├── test.php // Este é o script de teste que deve ser criado
└── Workerman // Diretório de código-fonte do Workerman, não altere o código aqui
```
1. Crie o diretório Protocols e crie um arquivo de protocolo
Protocols/MyTextProtocol.php (referindo-se à estrutura de diretório acima)
```php
// O namespace do protocolo definido pelo usuário deve ser unificado como Protocols
namespace Protocols;
// Protocolo de texto simples, formato do protocolo é texto + nova linha
class MyTextProtocol
{
// Função de fragmentação, retorna o comprimento do pacote atual
public static function input($recv_buffer)
{
// Busca o caractere de nova linha
$pos = strpos($recv_buffer, "\n");
// Se o caractere de nova linha não for encontrado, significa que não é um pacote completo, retorna 0 e continua esperando dados
if($pos === false)
{
return 0;
}
// Se o caractere de nova linha for encontrado, retorna o comprimento do pacote atual, incluindo o caractere de nova linha
return $pos+1;
}
// Após receber um pacote completo, é decodificado automaticamente através do decode, aqui apenas removemos o caractere de nova linha
public static function decode($recv_buffer)
{
return trim($recv_buffer);
}
// Antes de enviar dados para o cliente, será automaticamente codificado através do encode, e então enviado ao cliente, aqui adicionamos nova linha
public static function encode($data)
{
return $data."\n";
}
}
```
2. Utilize o protocolo MyTextProtocol para escutar e processar requisições
Crie o arquivo test.php referindo-se à estrutura de diretório final acima
```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");
/*
* Ao receber um dado completo (terminando com nova linha), executa automaticamente MyTextProtocol::decode('dado recebido')
* O resultado é passado para o callback onMessage através da variável $data
*/
$text_worker->onMessage = function(TcpConnection $connection, $data)
{
var_dump($data);
/*
* Para enviar dados ao cliente, MyTextProtocol::encode('hello world') será automaticamente chamado para codificação do protocolo,
* e então enviado ao cliente.
*/
$connection->send("hello world");
};
// Executa todos os workers
Worker::runAll();
```
3. Teste
Abra um terminal, acesse o diretório onde está o test.php e execute ```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. Início bem-sucedido.
```
Abra outro terminal e utilize telnet para teste (recomenda-se usar telnet do sistema linux)
Supondo que é um teste local,
no terminal execute telnet 127.0.0.1 5678
em seguida digite hi e pressione enter
você receberá os dados 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
```