Guia de atualização 1.5

Faça backup antes de atualizar e execute o seguinte comando para atualizar
composer require workerman/webman-framework ^1.5 -W && composer require webman/console ^1.2.12 && php webman install

Características e Alterações

Suporta workerman v5 fibras

Dica
workerman v5 requere PHP>=8.1
Comando de atualização do workerman composer require workerman/workerman ^5.0.0 -W
As fibras requerem a instalação de composer require revolt/event-loop ^1.0.0

Exemplos

Resposta atrasada

<?php

namespace app\controller;

use support\Request;
use Workerman\Timer;

class TestController
{
    public function index(Request $request)
    {
        // Aguarda 1,5 segundos
        Timer::sleep(1.5);
        return $request->getRemoteIp();
    }
}

Timer::sleep() é semelhante à função sleep() nativa do PHP, a diferença é que Timer::sleep() não bloqueia o processo.

Enviar uma requisição HTTP

Atenção
É necessário instalar composer require workerman/http-client ^2.0.0

<?php

namespace app\controller;

use support\Request;
use Workerman\Http\Client;

class TestController
{
    public function index(Request $request)
    {
        static $client;
        $client = $client ?: new Client();
        $response = $client->get('http://example.com'); // Inicia uma solicitação assíncrona de forma síncrona
        return $response->getBody()->getContents();
    }
}

Da mesma forma, a solicitação $client->get() não é bloqueante, isso pode ser usado para manipular solicitações http de forma não bloqueante no webman, melhorando o desempenho.

Para mais informações, consulte workerman/http-client

Adicionando a classe support\Context

A classe support\Context é usada para armazenar dados relacionados à solicitação. Quando a solicitação é concluída, os dados de contexto correspondentes são excluídos automaticamente. Ou seja, o ciclo de vida dos dados de contexto segue o ciclo de vida da solicitação.

Poluição de variáveis globais

No ambiente de fibra, é proibido armazenar informações de estado relacionadas à solicitação em variáveis globais ou estáticas, pois isso pode causar poluição de variáveis globais, por exemplo:

<?php

namespace app\controller;

use support\Request;
use Workerman\Timer;

class TestController
{
    protected static $name = '';

    public function index(Request $request)
    {
        static::$name = $request->get('name');
        Timer::sleep(5);
        return static::$name;
    }
}

Quando o número de processos é configurado como 1, ao enviar duas solicitações consecutivas:
http://127.0.0.1:8787/test?name=lilei
http://127.0.0.1:8787/test?name=hanmeimei
Esperamos que os resultados das duas solicitações retornem respectivamente lilei e hanmeimei, mas na verdade ambos retornam hanmeimei.
Isso ocorre porque a segunda solicitação sobrescreve a variável estática $name, e quando a primeira solicitação conclui a espera, a variável estática $name já se tornou hanmeimei.

O método correto é usar o contexto para armazenar dados de estado da solicitação

<?php

namespace app\controller;

use support\Request;
use support\Context;
use Workerman\Timer;

class TestController
{
    public function index(Request $request)
    {
        Context::set('name', $request->get('name'));
        Timer::sleep(5);
        return Context::get('name');
    }
}

Variáveis locais não causam poluição de dados

<?php

namespace app\controller;

use support\Request;
use support\Context;
use Workerman\Timer;

class TestController
{
    public function index(Request $request)
    {
        $name = $request->get('name');
        Timer::sleep(5);
        return $name;
    }
}

Porque $name é uma variável local, as fibras não podem acessar as variáveis locais umas das outras, portanto o uso de variáveis locais é seguro em ambiente de fibra.

Sobre as Fibras

As fibras não são a solução para todos os problemas. A introdução de fibras significa que é necessário estar atento à poluição de variáveis globais/estáticas e configurar o contexto. Além disso, depurar bugs em um ambiente de fibra é mais complicado do que a programação de bloqueio.

Na verdade, a programação de bloqueio do webman já é rápida o suficiente. De acordo com os dados dos testes techempower.com dos últimos três anos, o webman com operações de banco de dados supera em quase 1 vez o desempenho dos frameworks web do Go, como gin e echo, e é quase 40 vezes mais rápido do que frameworks tradicionais como Laravel.

Quando o banco de dados e o Redis estão na intranet, a programação de bloqueio de vários processos pode ter um desempenho melhor do que as fibras. Isso ocorre porque, quando o banco de dados e o Redis são rápidos o suficiente, o custo de criação, programação e destruição de fibras pode ser maior do que o custo de troca de processos, portanto, a introdução de fibras pode não melhorar significativamente o desempenho.

Quando usar as Fibras

Quando ocorrem acessos lentos durante a operação, como a necessidade de acessar uma API de terceiros, é possível usar workerman/http-client para fazer chamadas HTTP assíncronas usando fibras, aumentando a capacidade de concorrência do aplicativo.