دليل الترقية 1.5

يرجى إجراء نسخ احتياطي قبل الترقية، وتنفيذ الأوامر التالية للترقية
composer require workerman/webman-framework ^1.5 -W && composer require webman/console ^1.2.12 && php webman install

ميزات الوظيفة والتغييرات

دعم workerman v5 التعاقب

ملحوظة
يتطلب workerman v5 PHP>=8.1
أمر ترقية workerman composer require workerman/workerman ^5.0.0 -W
يتطلب التعاقب Fiber التثبيت composer require revolt/event-loop ^1.0.0

مثال

تأخير الاستجابة

<?php

namespace app\controller;

use support\Request;
use Workerman\Timer;

class TestController
{
    public function index(Request $request)
    {
        // نوم لمدة 1.5 ثانية
        Timer::sleep(1.5);
        return $request->getRemoteIp();
    }
}

Timer::sleep() شبيهة بدالة sleep() الخاصة بـ PHP، والاختلاف هو أن Timer::sleep() لا تحجب العملية

إجراء طلب HTTP

ملاحظة
يتطلب التثبيت 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'); // طريقة متزامنة لبدء الطلب غير المتزامن
        return $response->getBody()->getContents();
    }
}

بنفس طريقة $client->get() الطلب هو غير محجوب، ويمكن استخدامه في webman لمعالجة الطلبات HTTP بشكل غير محجوب لزيادة الأداء.

لمزيد من المعلومات، راجع workerman/http-client

إضافة فئة support\Context

تستخدم فئة support\Context لتخزين البيانات المتعلقة بالطلب، وعند اكتمال الطلب، سيتم حذف بيانات السياق المقابلة. وهذا يعني أن دورة حياة بيانات السياق تتبع دورة حياة الطلب.

تلوث المتغيرات العالمية

بيئة التعاقب تمنع تخزين معلومات الحالة المتعلقة بالطلب في المتغيرات العالمية أو المتغيرات الثابتة، حيث يمكن أن يؤدي هذا إلى تلوث المتغيرات العالمية. على سبيل المثال

<?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;
    }
}

عندما نقوم بتعيين عدد العمليات إلى 1، وعندما نقوم بإرسال طلبين متتاليين
http://127.0.0.1:8787/test?name=lilei
http://127.0.0.1:8787/test?name=hanmeimei
نتوقع أن يكون لكل من الطلبين نتيجة مختلفة تمامًا "lilei" و "hanmeimei" على التوالي، ولكن في الواقع، يتم إرجاع "hanmeimei" في كلا الطلبين.
ذلك بسبب كتابة المتغير الثابت "$name" في الطلب الثاني، وعند انتهاء النوم، يتم إجابة الطلب الأول حيث يكون قيمة المتغير الثابت "$name" قد تغيرت إلى "hanmeimei".

الوسيلة الصحيحة هي استخدام تخزين الحالة في السياق

<?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');
    }
}

المتغيرات المحلية لن تؤدي إلى تلوث البيانات

<?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;
    }
}

بما أن المتغير "$name" هو متغير محلي، فإنه لن يؤدي إلى تلوث البيانات بين العمليات، وعلى هذا النحو، فإن استخدام المتغيرات المحلية آمن من حيث العمليات.

حول التعاقب

التعاقب ليست الحل السحري، حيث أن إدخال التعاقب يعني أنه يجب الانتباه إلى مشكلة تلوث المتغيرات العالمية/المتغيرات الثابتة، ويجب تعيين سياق الوظيفة. بالإضافة إلى ذلك، تصحيح الأخطاء في بيئة التعاقب يعقد بعض الشيء مقارنة بالبرمجة التقليدية.

يعتبر البرمجة التقليدية في webman بالفعل سريعة بما فيه الكفاية، ويبين بيانات الاختبار الذي أجريه على مدى السنوات الثلاث الأخيرة من قبل techempower.com أن البرمجة التقليدية لـ webman باستخدام القاعدة deتَ تعامل قاعدة البيانات يفوق أداء إطار العمل go gin و echo بنسبة تقريبية 1 مرة، وأداءه يفوق إطار العمل التقليدي laravel بنسبة تصل إلى 40 مرة.

بشكل عام، عندما يكون قاعدة البيانات والـ redis موجودة داخل الشبكة الداخلية، فإن أداء البرمجة التقليدية المتعددة العمليات قد يكون أعلى بكثير من التعاقب، وذلك يرجع إلى أن تكلفة إنشاء التعاقب، جدولته، وتدميره يمكن أن تكون أكبر من تكلفة تبديل العمليات في حالة سرعة كافية لقواعد البيانات والـ redis. لذا، فإن إدخال التعاقب في هذا السياق لن يحسن الأداء بشكل كبير.

متى يجب استخدام التعاقب

عندما تكون هناك زيادة في الوقت اللازمة للوصول إلى الوظيفة، على سبيل المثال عندما تحتاج الوظيفة إلى الوصول إلى واجهة برمجة التطبيقات الخارجية، يمكن استخدام workerman/http-client بشكل متسلسل يشتمل على طريقة غير محجوبة لبدء استدعاءات HTTP غير المتزامنة، مما يزيد من قدرة التطبيق على الموازاة.