workerman/http-client
Açıklama
workerman/http-client asenkron bir http istemci bileşenidir. Tüm istek yanıtları asenkron ve bloklamasızdır, yerleşik bir bağlantı havuzu içerir, mesaj istekleri ve yanıtları PSR7 standardına uygundur.
Kurulum:
composer require workerman/http-client
Örnekler:
get ve post isteği kullanımı
use Workerman\Worker;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker();
$worker->onWorkerStart = function () {
$http = new Workerman\Http\Client();
$http->get('https://example.com/', function ($response) {
var_dump($response->getStatusCode());
echo $response->getBody();
}, function ($exception) {
echo $exception;
});
$http->post('https://example.com/', ['key1' => 'value1', 'key2' => 'value2'], function ($response) {
var_dump($response->getStatusCode());
echo $response->getBody();
}, function ($exception) {
echo $exception;
});
$http->request('https://example.com/', [
'method' => 'POST',
'version' => '1.1',
'headers' => ['Connection' => 'keep-alive'],
'data' => ['key1' => 'value1', 'key2' => 'value2'],
'success' => function ($response) {
echo $response->getBody();
},
'error' => function ($exception) {
echo $exception;
}
]);
};
Worker::runAll();
Dosya yükleme
<?php
use Workerman\Worker;
require_once 'vendor/autoload.php';
$worker = new Worker();
$worker->onWorkerStart = function () {
$http = new Workerman\Http\Client();
// Dosya yükle
$multipart = new \Workerman\Psr7\MultipartStream([
[
'name' => 'file',
'contents' => fopen(__FILE__, 'r')
],
[
'name' => 'json',
'contents' => json_encode(['a'=>1, 'b'=>2])
]
]);
$boundary = $multipart->getBoundary();
$http->request('http://127.0.0.1:8787', [
'method' => 'POST',
'version' => '1.1',
'headers' => ['Connection' => 'keep-alive', 'Content-Type' => "multipart/form-data; boundary=$boundary"],
'data' => $multipart,
'success' => function ($response) {
echo $response->getBody();
},
'error' => function ($exception) {
echo $exception;
}
]);
};
Worker::runAll();
progress akışlı dönüş
<?php
require_once __DIR__ . '/vendor/autoload.php';
use Workerman\Connection\TcpConnection;
use Workerman\Http\Client;
use Workerman\Protocols\Http\Chunk;
use Workerman\Protocols\Http\Request;
use Workerman\Protocols\Http\Response;
use Workerman\Worker;
$worker = new Worker('http://0.0.0.0:1234');
$worker->onMessage = function (TcpConnection $connection, Request $request) {
$http = new Client();
$http->request('https://api.ai.com/v1/chat/completions', [
'method' => 'POST',
'data' => json_encode([
'model' => 'gpt-3.5-turbo',
'temperature' => 1,
'stream' => true,
'messages' => [['role' => 'user', 'content' => 'hello']],
]),
'headers' => [
'Content-Type' => 'application/json',
'Authorization' => 'Bearer sk-xxx',
],
'progress' => function($buffer) use ($connection) {
$connection->send(new Chunk($buffer));
},
'success' => function($response) use ($connection) {
$connection->send(new Chunk('')); // Boş bir chunk göndermek, yanıtın bittiğini belirtir.
},
]);
$connection->send(new Response(200, [
//"Content-Type" => "application/octet-stream",
"Transfer-Encoding" => "chunked",
], ''));
};
Worker::runAll();
Optinons Seçenekleri
<?php
require __DIR__ . '/vendor/autoload.php';
use Workerman\Worker;
$worker = new Worker();
$worker->onWorkerStart = function(){
$options = [
'max_conn_per_addr' => 128, // Her bir alan adı için maksimum eşzamanlı bağlantı sayısı
'keepalive_timeout' => 15, // Bağlantının ne kadar süre kullanılmadığında kapatılacağı
'connect_timeout' => 30, // Bağlantı zaman aşımı süresi
'timeout' => 30, // İstek yapıldıktan sonra yanıt bekleme zaman aşımı süresi
];
$http = new Workerman\Http\Client($options);
$http->get('http://example.com/', function($response){
var_dump($response->getStatusCode());
echo $response->getBody();
}, function($exception){
echo $exception;
});
};
Worker::runAll();
Koşut Kullanımı
Dikkat
Koşut kullanımı için workerman>=5.1, http-client>=3.0,swooleveyaswowuzantısını yüklemeniz veyacomposer require revolt/event-loopyükleyerek Fiber sürücüsünü desteklemeniz gerekir.
use Workerman\Worker;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker();
$worker->eventLoop = \Workerman\Events\Swoole::class; // Veya \Workerman\Events\Swow::class ya da \Workerman\Events\Fiber::class
$worker->onWorkerStart = function () {
$http = new Workerman\Http\Client();
$response = $http->get('https://example.com/');
var_dump($response->getStatusCode());
echo $response->getBody();
$response = $http->post('https://example.com/', ['key1' => 'value1', 'key2' => 'value2']);
var_dump($response->getStatusCode());
echo $response->getBody();
$response = $http->request('https://example.com/', [
'method' => 'POST',
'version' => '1.1',
'headers' => ['Connection' => 'keep-alive'],
'data' => ['key1' => 'value1', 'key2' => 'value2'],
]);
echo $response->getBody();
};
Worker::runAll();
Callback fonksiyonu ayarlanmadığında, istemci asenkron istek sonucunu senkron bir şekilde dönecektir; istek süreci mevcut süreci bloklamaz, yani istekleri eşzamanlı işleyebilir.
Dikkat:
-
Proje öncelikle
require __DIR__ . '/vendor/autoload.php';yüklemelidir. -
Tüm asenkron kodlar yalnızca workerman başlatıldıktan sonra çalıştırma ortamında çalıştırılabilir.
-
Workerman tabanlı tüm projeleri destekler, bunlar arasında Webman, GatewayWorker, PHPSocket.io vb. bulunmaktadır.
-
Client nesnesini mümkün olduğunca saklayıp yeniden kullanmak, bağlantı havuzundan tam olarak yararlanmayı sağlar ve performansı artırır, her seferinde
new Workerman\Http\Client()ile nesne oluşturulmamalıdır.
webman'deki kullanım
Eğer webman içinde asenkron http istekleri yapıp sonuçları ön tarafa döndürmek istiyorsanız, aşağıdaki kullanıma bakabilirsiniz.
<?php
namespace app\controller;
use support\Request;
use support\Response;
use Workerman\Protocols\Http\Chunk;
class IndexController
{
public function index(Request $request)
{
// client nesnesini saklayıp yeniden kullanarak performansı önemli ölçüde artırın.
static $http;
$connection = $request->connection;
$http = $http ?: new \Workerman\Http\Client();
$http->get('https://example.com/', function ($response) use ($connection) {
$connection->send(new Chunk($response->getBody()));
$connection->send(new Chunk('')); // Boş bir chunk göndermek, yanıtın bittiğini belirtir.
});
return response()->withHeaders([
"Transfer-Encoding" => "chunked",
]);
}
}
Yukarıdaki kullanım, istemciye chunked bir http başlığı ile dönüş yapar, ardından verileri chunk şeklinde istemciye gönderir. Tabii ki, yukarıdaki koşut kullanımına da bakabilirsiniz.
Dikkat
Yukarıdaki kod, client nesnesini yeniden kullanmak için yöntem kapsamındaki statik bir değişkende saklanmıştır, aslında bunu sınıfın statik üyesine veya global bir nesneye de saklayabilirsiniz.
webman'de OpenAI arayüzüne istek yapıp akışlı yanıt döndürme
Referans: https://www.workerman.net/plugin/157