توضيح
ابتداءً من الإصدار 4.x، عزز Workerman دعم خدمات HTTP. تم إدخال فئات الطلبات، الاستجابات، الجلسات، وSSE. إذا كنت ترغب في استخدام خدمات HTTP الخاصة بـ Workerman، يُنصح بشدة باستخدام إصدار Workerman 4.x أو إصدار أعلى منه.
لاحظ أن التفاصيل أدناه تخص استخدام Workerman 4.x، وهي غير متوافقة مع Workerman 3.x.
ملاحظات
- إلا إذا كانت الاستجابة عبارة عن chunk أو استجابة SSE، فلا يُسمح بإرسال عدة استجابات في طلب واحد، مما يعني أنه لا يُسمح بالاتصال بـ
$connection->send()عدة مرات في نفس الطلب. - يجب استدعاء
$connection->send()مرة واحدة على الأقل في كل طلب لإرسال الاستجابة، وإلا سيستمر العميل في الانتظار.
استجابة سريعة
عندما لا تحتاج إلى تغيير رمز حالة HTTP (افتراضي 200)، أو تخصيص رأس، أو ملف تعريف الارتباط، يمكنك ببساطة إرسال سلسلة إلى العميل لإكمال الاستجابة.
مثال
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)
{
// أرسل مباشرة this is body إلى العميل
$connection->send("this is body");
};
// تشغيل العامل
Worker::runAll();
تغيير رمز الحالة
عندما تحتاج إلى تخصيص رمز الحالة، الرأس، أو ملف تعريف الارتباط، تحتاج إلى استخدام فئة الاستجابة Workerman\Protocols\Http\Response. على سبيل المثال، في المثال أدناه، يتم إرجاع رمز الحالة 404 عند الوصول إلى المسار /404، ومحتوى الجسم هو <h1>عذرًا، الملف غير موجود</h1>.
مثال
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>عذرًا، الملف غير موجود</h1>'));
} else {
$connection->send('this is body');
}
};
// تشغيل العامل
Worker::runAll();
عند تهيئة فئة Response، إذا كنت تريد تغيير رمز الحالة، استخدم الطريقة التالية.
$response = new Response(200);
$response->withStatus(404);
$connection->send($response);
إرسال الرأس
بالمثل، يتطلب إرسال الرأس استخدام فئة الاستجابة Workerman\Protocols\Http\Response.
مثال
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 Value'
], 'this is body');
$connection->send($response);
};
// تشغيل العامل
Worker::runAll();
بعد تهيئة فئة Response، إذا كنت ترغب في إضافة أو تغيير الرأس، استخدم الطريقة التالية.
$response = new Response(200);
// إضافة أو تغيير رأس واحد
$response->header('Content-Type', 'text/html');
// إضافة أو تغيير عدة رؤوس
$response->withHeaders([
'Content-Type' => 'application/ json',
'X-Header-One' => 'Header Value'
]);
$connection->send($response);
إعادة التوجيه
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::runAll();
إرسال ملف تعريف الارتباط
بالمثل، يتطلب إرسال ملف تعريف الارتباط استخدام فئة الاستجابة Workerman\Protocols\Http\Response.
مثال
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::runAll();
إرسال ملف
بالمثل، يتطلب إرسال ملف استخدام فئة الاستجابة Workerman\Protocols\Http\Response.
لإرسال ملف، استخدم الطريقة التالية
$response = (new Response())->withFile($file);
$connection->send($response);
- يدعم Workerman إرسال ملفات كبيرة جدًا
- بالنسبة للملفات الكبيرة (أكثر من 2 ميغابايت)، لن يقوم Workerman بقراءة الملف بالكامل في الذاكرة دفعة واحدة، بل سيقوم بقراءة الملف في أجزاء وإرساله في الوقت المناسب
- سيقوم Workerman بتحسين سرعة قراءة الملف وإرساله بناءً على سرعة استقبال العميل، لضمان إرسال الملفات بأسرع ما يمكن مع تقليل استخدام الذاكرة إلى أدنى حد
- إرسال البيانات غير متزامن، ولن يؤثر على معالجة الطلبات الأخرى
- عند إرسال ملف، سيتم تلقائيًا إضافة رأس
Last-Modifiedللسماح للخادم بتحديد ما إذا كان يجب إرسال استجابة 304 في الطلبات التالية لتوفير نقل الملفات وزيادة الأداء - سيتم تلقائيًا إرسال الملف باستخدام رأس
Content-Typeالمناسب إلى المتصفح - إذا كان الملف غير موجود، سيتم تحويله تلقائيًا إلى استجابة 404
مثال
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 لتحديد ما إذا تم تعديل الملف
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();
// إذا لم يتم تعديل الملف، أعد 304
if ($modified_time === $if_modified_since) {
$connection->send(new Response(304));
return;
}
}
// إذا كان الملف قد تم تعديله أو لم يكن هناك رأس if-modified-since، أرسل الملف
$response = (new Response())->withFile($file);
$connection->send($response);
};
// تشغيل العامل
Worker::runAll();
إرسال بيانات HTTP Chunk
- يجب أولاً إرسال استجابة تحتوي على رأس
Transfer-Encoding: chunkedإلى العميل - يتم استخدام فئة
Workerman\Protocols\Http\Chunkلإرسال بيانات chunk التالية - يجب في النهاية إرسال chunk فارغ لإنهاء الاستجابة
مثال
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)
{
// أولاً، أرسل استجابة تحمل رأس Transfer-Encoding: chunked
$connection->send(new Response(200, array('Transfer-Encoding' => 'chunked'), 'hello'));
// بيانات Chunk التالية يتم إرسالها باستخدام فئة Workerman\Protocols\Http\Chunk
$connection->send(new Chunk('الجزء الأول من البيانات'));
$connection->send(new Chunk('الجزء الثاني من البيانات'));
$connection->send(new Chunk('الجزء الثالث من البيانات'));
// أخيرًا، يجب إرسال chunk فارغ لإنهاء الاستجابة
$connection->send(new Chunk(''));
};
// تشغيل العامل
Worker::runAll();