Açıklama
workerman 4.x sürümünden itibaren HTTP hizmet desteğini artırdı. İstek sınıfı, yanıt sınıfı, oturum sınıfı ve SSE eklendi. workerman'ın HTTP hizmetini kullanmak istiyorsanız, workerman 4.x veya daha sonraki sürümlerin kullanılması şiddetle önerilir.
Aşağıdaki tüm kullanım şekilleri workerman 4.x sürümüne aittir, workerman 3.x ile uyumlu değildir.
Dikkat
- Eğer gönderilen bir chunk veya SSE yanıtı değilse, bir istekte birden fazla yanıt göndermek yasaktır; yani bir istekte birden fazla kez
'$connection->send()'çağrısı yapılamaz. - Her istek sonunda bir kez
'$connection->send()'çağrısı yaparak yanıt göndermek gereklidir, aksi takdirde istemci sürekli bekleyecektir.
Hızlı Yanıt
HTTP durum kodunu (varsayılan 200) değiştirmeye ya da özel başlık, çerez ayarlamaya gerek olmadığında, yanıtı tamamlamak için istemciye doğrudan bir dize gönderebilirsiniz.
Örnek
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:8080');
$worker->onMessage = function(TcpConnection $connection, Request $request)
{
// İstemciye bu body'i doğrudan gönder
$connection->send("this is body");
};
// Worker'ı çalıştır
Worker::runAll();
Durum Kodunu Değiştirme
Özel durum kodu, başlık, çerez ayarlamak gerektiğinde Workerman\Protocols\Http\Response yanıt sınıfını kullanmak gerekir. Aşağıdaki örnekte /404 yolu ile erişildiğinde 404 durum kodu döndürülmekte ve içerik <h1>Üzgünüm, dosya bulunamadı</h1> olmaktadır.
Örnek
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
use Workerman\Protocols\Http\Request;
use Workerman\Protocols\Http\Response;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker('http://0.0.0.0:8080');
$worker->onMessage = function(TcpConnection $connection, Request $request)
{
if ($request->path() === '/404') {
$connection->send(new Response(404, [], '<h1>Üzgünüm, dosya bulunamadı</h1>'));
} else {
$connection->send('this is body');
}
};
// Worker'ı çalıştır
Worker::runAll();
Response sınıfı zaten başlatıldıktan sonra, durum kodunu değiştirmek için aşağıdaki yöntemi kullanabilirsiniz.
$response = new Response(200);
$response->withStatus(404);
$connection->send($response);
Başlık Gönderme
Aynı şekilde, başlık göndermek için Workerman\Protocols\Http\Response yanıt sınıfını kullanmak gerekir.
Örnek
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
use Workerman\Protocols\Http\Request;
use Workerman\Protocols\Http\Response;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker('http://0.0.0.0:8080');
$worker->onMessage = function(TcpConnection $connection, Request $request)
{
$response = new Response(200, [
'Content-Type' => 'text/html',
'X-Header-One' => 'Header Değeri'
], 'this is body');
$connection->send($response);
};
// Worker'ı çalıştır
Worker::runAll();
Response sınıfı zaten başlatıldıktan sonra, başlık eklemek veya değişiklik yapmak için aşağıdaki yöntemi kullanabilirsiniz.
$response = new Response(200);
// Bir başlık ekle veya değiştir
$response->header('Content-Type', 'text/html');
// Birden fazla başlık ekle veya değiştir
$response->withHeaders([
'Content-Type' => 'application/json',
'X-Header-One' => 'Header Değeri'
]);
$connection->send($response);
Yönlendirme
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
use Workerman\Protocols\Http\Request;
use Workerman\Protocols\Http\Response;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker('http://0.0.0.0:8080');
$worker->onMessage = function(TcpConnection $connection, Request $request)
{
$location = '/test_location';
$response = new Response(302, ['Location' => $location]);
$connection->send($response);
};
// Worker'ı çalıştır
Worker::runAll();
Çerez Gönderme
Aynı şekilde, çerez göndermek için Workerman\Protocols\Http\Response yanıt sınıfını kullanmak gerekir.
Örnek
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
use Workerman\Protocols\Http\Request;
use Workerman\Protocols\Http\Response;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker('http://0.0.0.0:8080');
$worker->onMessage = function(TcpConnection $connection, Request $request)
{
$response = new Response(200, [], 'this is body');
$response->cookie('name', 'tom');
$connection->send($response);
};
// Worker'ı çalıştır
Worker::runAll();
Dosya Gönderme
Aynı şekilde, dosya göndermek için Workerman\Protocols\Http\Response yanıt sınıfını kullanmak gerekir.
Dosya gönderirken aşağıdaki yolu kullanın.
$response = (new Response())->withFile($file);
$connection->send($response);
- workerman büyük dosyaları göndermeyi destekler
- Büyük dosyalar (2M'den fazla) için, workerman dosyayı bir bütün olarak belleğe okumayacak; uygun bir zamanda bölümler halinde okuyup gönderecek
- workerman, istemcinin alma hızına göre dosya okuma ve gönderme hızını optimize edecektir, böylece dosya gönderirken bellek kullanımını minimumda tutarak en hızlı şekilde dosya göndermeyi sağlamak
- Veri gönderimi kesintisizdir, diğer isteklerin işlenmesini etkilemez
- Dosya gönderirken otomatik olarak
Last-Modifiedbaşlığı eklenecek, böylece bir sonraki istek için sunucu 304 yanıtı gönderebilecektir ve dosya transferi ile performans artırılacaktır - Gönderilen dosya otomatik olarak uygun
Content-Typebaşlığı ile tarayıcıya iletilecektir - Eğer dosya yoksa, otomatik olarak 404 yanıtına dönüştürülecektir
Örnek
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
use Workerman\Protocols\Http\Request;
use Workerman\Protocols\Http\Response;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker('http://0.0.0.0:8080');
$worker->onMessage = function(TcpConnection $connection, Request $request)
{
$file = '/your/path/of/file';
// if-modified-since başlığını kontrol ederek dosyanın değiştirilip değiştirilmediğini kontrol et
if (!empty($if_modified_since = $request->header('if-modified-since'))) {
$modified_time = date('D, d M Y H:i:s', filemtime($file)) . ' ' . \date_default_timezone_get();
// Dosya değiştirilmemişse 304 döndür
if ($modified_time === $if_modified_since) {
$connection->send(new Response(304));
return;
}
}
// Dosya değiştirilmiş ya da if-modified-since başlığı yoksa dosyayı gönder
$response = (new Response())->withFile($file);
$connection->send($response);
};
// Worker'ı çalıştır
Worker::runAll();
HTTP Chunk Verisi Gönderme
- Öncelikle istemciye
Transfer-Encoding: chunkedbaşlığı taşıyan bir Yanıt gönderilmelidir - Sonraki chunk verileri için
Workerman\Protocols\Http\Chunksınıfını kullanın - Yanıtı sonlandırmak için mutlaka boş bir chunk göndermelisiniz
Örnek
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
use Workerman\Protocols\Http\Request;
use Workerman\Protocols\Http\Response;
use Workerman\Protocols\Http\Chunk;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker('http://0.0.0.0:8080');
$worker->onMessage = function(TcpConnection $connection, Request $request)
{
// Öncelikle Transfer-Encoding: chunked başlığı taşıyan bir Yanıt gönder
$connection->send(new Response(200, array('Transfer-Encoding' => 'chunked'), 'hello'));
// Sonraki Chunk verileri için Workerman\Protocols\Http\Chunk sınıfını kullan
$connection->send(new Chunk('Birinci bölüm verisi'));
$connection->send(new Chunk('İkinci bölüm verisi'));
$connection->send(new Chunk('Üçüncü bölüm verisi'));
// Son olarak boş bir chunk göndererek yanıtı bitirmelisin
$connection->send(new Chunk(''));
};
// Worker'ı çalıştır
Worker::runAll();