مشغل Azure Web PubSub وروابطه لوظائف Azure

يشرح هذا المرجع كيفية معالجة أحداث Web PubSub في Azure Functions.

Web PubSub هي خدمة مدارة من Azure تساعد المطورين على إنشاء تطبيقات ويب بسهولة مع ميزات في الوقت الحقيقي ونمط النشر والاشتراك.

الإجراء نوع
تشغيل دالة عندما تأتي الرسائل من الخدمة ربط التشغيل
ربط الطلب باستهداف الكائن ضمن مشغل Http للتفاوض وطلبات المصدر ربط الإدخال
استدعاء إجراءات تنفيذ الخدمة ربط الإخراج

الوثائق | المرجعية لحزمة التعليمات البرمجية | | المصدر API وثائق | المنتج عينات

الإضافة إلى تطبيق الوظائف الخاص بك

يتطلب العمل مع المشغل والروابط الرجوع إلى الحزمة المناسبة. تُستخدم حزمة NuGet لمكتبات فئة .NET؛ بينما تُستخدم حزمة الملحق لكافة أنواع التطبيقات الأخرى.

اللغة أضف بواسطة... ملاحظات
C#‎ تثبيت حزمة NuGet، الإصدار التجريبي
C# Script, JavaScript, Python, PowerShell تثبيت الملحقات بشكل صريح، استخدام حزم الملحقات يوصى باستخدام ملحق أدوات Azure مع Visual Studio Code.
C# Script (عبر الإنترنت فقط في مدخل Azure) إضافة ربط لتحديث ملحقات الربط الموجودة دون الحاجة إلى إعادة نشر تطبيق الوظائف، راجع تحديث الإضافات.

المفاهيم الرئيسية

Diagram showing the workflow of Azure Web PubSub service working with Function Apps.

(1)-(2) WebPubSubConnection ربط الإدخال مع HttpTrigger لإنشاء اتصال العميل.

(3)-(4) WebPubSubTrigger ربط المشغل أو WebPubSubContext ربط الإدخال باستخدام HttpTrigger لمعالجة طلب الخدمة.

(5)-(6) WebPubSub ربط الإخراج لطلب الخدمة القيام بشيء ما.

ربط التشغيل

استخدم مشغل الدالة لمعالجة الطلبات من خدمة Azure Web PubSub.

WebPubSubTrigger يستخدم عندما تحتاج إلى معالجة الطلبات من جانب الخدمة. سيكون نمط نقطة نهاية المشغل كما يلي الذي يجب تعيينه في جانب خدمة Web PubSub (المدخل: الإعدادات -> معالج الأحداث -> قالب URL). في نمط نقطة النهاية، يكون جزء code=<API_KEY> الاستعلام مطلوبا عند استخدام Azure Function App لأسباب أمنية. يمكن العثور على المفتاح في مدخل Microsoft Azure. ابحث عن مورد تطبيق الوظائف وانتقل إلى Functions ->App keys ->System keys ->webpubsub_extension بعد نشر تطبيق الوظائف إلى Azure. على الرغم من ذلك، لا يلزم هذا المفتاح عند العمل مع الوظائف المحلية.

<Function_App_Url>/runtime/webhooks/webpubsub?code=<API_KEY>

Screenshot of get function system keys.

مثال

[FunctionName("WebPubSubTrigger")]
public static void Run(
    [WebPubSubTrigger("<hub>", WebPubSubEventType.User, "message")] UserEventRequest request, ILogger log)
{
    log.LogInformation($"Request from: {request.ConnectionContext.UserId}");
    log.LogInformation($"Request message data: {request.Data}");
    log.LogInformation($"Request message dataType: {request.DataType}");
}

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

[FunctionName("WebPubSubTriggerReturnValueFunction")]
public static UserEventResponse Run(
    [WebPubSubTrigger("hub", WebPubSubEventType.User, "message")] UserEventRequest request)
{
    return request.CreateResponse(BinaryData.FromString("ack"), WebPubSubDataType.Text);
}

السمات والتعليقات التوضيحية

في مكتبات الفئة C#، استخدم السمة WebPubSubTrigger .

فيما يلي سمة WebPubSubTrigger في توقيع أسلوب:

[FunctionName("WebPubSubTrigger")]
public static void Run([WebPubSubTrigger("<hub>", <WebPubSubEventType>, "<event-name>")] 
    WebPubSubConnectionContext context, ILogger log)
{
    ...
}

للحصول على مثال كامل، راجع مثال C#‎.

التكوين

يشرح الجدول الآتي خصائص تكوين ربط البيانات التي عليك تعيينها في ملف function.json.

خاصية function.json خاصية السمة ‏‏الوصف
النوع غير متوفر مطلوب - يجب تعيينه إلى webPubSubTrigger.
الاتجاه غير متوفر مطلوب - يجب تعيينه إلى in.
الاسم غير متوفر مطلوب - اسم المتغير المستخدم في التعليمة البرمجية للدالة للمعلمة التي تتلقى بيانات الحدث.
محور المركز مطلوب - يجب تعيين القيمة إلى اسم مركز Web PubSub للدالة التي سيتم تشغيلها. ندعم تعيين القيمة في السمة كأولوية أعلى، أو يمكن تعيينها في إعدادات التطبيق كقيمة عمومية.
نوع الحدث نوع حدث WebPubSub مطلوب - يجب تعيين القيمة كنوع الحدث من الرسائل للدالة التي سيتم تشغيلها. يجب أن تكون القيمة إما user أو system.
eventName EventName مطلوب - يجب تعيين القيمة كحدث رسائل للدالة التي سيتم تشغيلها.
بالنسبة system لنوع الحدث، يجب أن يكون اسم الحدث في connect، ، connected. disconnected
بالنسبة إلى البروتوكولات الفرعية المعرفة من قبل المستخدم، يكون اسم الحدث هو message.
بالنسبة إلى البروتوكول json.webpubsub.azure.v1.الفرعي المدعوم من قبل النظام، يكون اسم الحدث هو اسم الحدث المعرف من قبل المستخدم.
الاتصال Connection اختياري - اسم إعدادات التطبيق أو مجموعة الإعدادات التي تحدد خدمة Azure Web PubSub الأولية. يتم استخدام القيمة للتحقق من صحة التوقيع. ويتم حل القيمة تلقائيا باستخدام إعدادات التطبيق "WebPubSub الاتصال ionString" بشكل افتراضي. ويعني null أن التحقق من الصحة غير مطلوب وينجح دائما.

استخدامات

في C#، WebPubSubEventRequest هو نوع معلمة الربط المتعرف عليها، ومعلمات rest مرتبطة باسم المعلمة. تحقق من الجدول أدناه للمعلمات والأنواع المتوفرة.

في لغة مكتوبة بشكل ضعيف مثل JavaScript، name يتم استخدام في function.json لربط كائن المشغل فيما يتعلق بجدول التعيين أدناه. واحترام dataTypefunction.json تحويل الرسالة وفقا لذلك عند name تعيين إلى data كعنصر ربط لإدخال المشغل. يمكن قراءة جميع المعلمات من context.bindingData.<BindingName> ويتم JObject تحويلها.

اسم الربط نوع الربط ‏‏الوصف خصائص
طلب WebPubSubEventRequest يصف الطلب المصدر تختلف الخاصية حسب أنواع الأحداث المختلفة، بما في ذلك الفئات المشتقة ConnectEventRequestو ConnectedEventRequestUserEventRequest و وDisconnectedEventRequest
connectionContext WebPubSubConnectionContext معلومات الطلب الشائعة EventType, EventName, Hub, الاتصال ionId, UserId, Headers, Origin, Signature, States
البيانات BinaryData،string،،Streambyte[] طلب بيانات الرسالة من العميل في حدث المستخدم message -
dataType WebPubSubDataType طلب رسالة dataType، الذي يدعم binary، ، textjson -
المطالبات IDictionary<string, string[]> مطالبات المستخدم في طلب النظام connect -
استعلام IDictionary<string, string[]> استعلام المستخدم في طلب النظام connect -
البروتوكولات الفرعية IList<string> البروتوكولات الفرعية المتوفرة في طلب النظام connect -
شهادات العميل IList<ClientCertificate> قائمة ببصمة إبهام الشهادة من العملاء في طلب النظام connect -
السبب string السبب في طلب النظام disconnected -

هام

في C#، يجب وضع معلمة معتمدة بأنواع متعددة في الأول، أي datarequest غير النوع الافتراضي BinaryData لجعل الدالة ملزمة بشكل صحيح.

استجابة الإرجاع

WebPubSubTrigger يحترم استجابة العميل التي تم إرجاعها للأحداث المتزامنة لحدث connect المستخدم و. يتم إرسال الاستجابة المتطابقة فقط إلى الخدمة، وإلا يتم تجاهلها. بالإضافة إلى ذلك، WebPubSubTrigger يدعم كائن الإرجاع المستخدمين إلى SetState() وإدارة ClearStates() بيانات التعريف للاتصال. ويدمج الملحق النتائج من القيمة المرجعة مع القيم الأصلية من الطلب WebPubSubConnectionContext.States. تتم الكتابة فوق القيمة الموجودة في المفتاح الموجود وتضاف القيمة في المفتاح الجديد.

نوع الإرجاع ‏‏الوصف خصائص
ConnectEventResponse الاستجابة للحدث connect المجموعات، الأدوار، معرف المستخدم، البروتوكول الفرعي
UserEventResponse الاستجابة لحدث المستخدم نوع البيانات، البيانات
EventErrorResponse استجابة الخطأ لحدث المزامنة Code, ErrorMessage
*WebPubSubEventResponse نوع الاستجابة الأساسية للردود المدعومة المستخدمة لحالات العودة غير المؤكدة -

ربط بيانات الإدخال

يوفر ملحقنا رابطي إدخال يستهدفان احتياجات مختلفة.

  • WebPubSubConnection

    للسماح لعميل بالاتصال بخدمة Azure Web PubSub، يجب أن يعرف عنوان URL لنقطة نهاية الخدمة ورمز وصول صالح. WebPubSubConnection ينتج ربط الإدخال المعلومات المطلوبة، لذلك لا يحتاج العميل إلى التعامل مع جيل الرمز المميز نفسه. نظرا لأن الرمز المميز محدود زمنيا ويمكن استخدامه لمصادقة مستخدم معين على اتصال، فلا تقم بالتخزين المؤقت للرمز المميز أو مشاركته بين العملاء. يمكن استخدام مشغل HTTP يعمل مع ربط الإدخال هذا للعملاء لاسترداد معلومات الاتصال.

  • WebPubSubContext

    عند استخدام هو Static Web Apps، HttpTrigger هو المشغل الوحيد المدعوم وضمن سيناريو Web PubSub، نقدم WebPubSubContext ربط الإدخال يساعد المستخدمين على إلغاء تسلسل طلب http المصدر من جانب الخدمة ضمن بروتوكولات Web PubSub. لذلك يمكن للعملاء الحصول على نتائج مماثلة WebPubSubTrigger مقارنة مع للتعامل بسهولة في الوظائف. راجع الأمثلة الواردة أدناه. عند استخدامه مع HttpTrigger، يتطلب العميل تكوين عنوان URL المكشوف ل HttpTrigger في معالج الأحداث وفقا لذلك.

المثال- WebPubSubConnection

يوضح المثال التالي دالة C# التي تحصل على معلومات اتصال Web PubSub باستخدام ربط الإدخال وتعيدها عبر HTTP. في المثال أدناه، UserId يتم تمرير من خلال جزء استعلام طلب العميل مثل ?userid={User-A}.

[FunctionName("WebPubSubConnectionInputBinding")]
public static WebPubSubConnection Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequest req,
    [WebPubSubConnection(Hub = "<hub>", UserId = "{query.userid}")] WebPubSubConnection connection)
{
    return connection;
}

الرموز المميزة المصادق عليها

إذا تم تشغيل الدالة بواسطة عميل مصادقة، يمكنك إضافة مطالبة معرف مستخدم إلى الرمز المميز الذي تم إنشاؤه. يمكنك بسهولة إضافة المصادقة إلى تطبيق دالة باستخدام مصادقة خدمة التطبيقات.

تقوم مصادقة خدمة التطبيق بتعيين عناوين HTTP المسماة x-ms-client-principal-id و x-ms-client-principal-nameالتي تحتوي على معرف واسم العميل الرئيسي للمستخدم المصادق عليه، على الترتيب.

يمكنك تعيين الخاصية UserId للربط إلى القيمة من عنوان باستخدام تعبير ربط: {headers.x-ms-client-principal-id} أو {headers.x-ms-client-principal-name}.

[FunctionName("WebPubSubConnectionInputBinding")]
public static WebPubSubConnection Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequest req,
    [WebPubSubConnection(Hub = "<hub>", UserId = "{headers.x-ms-client-principal-name}")] WebPubSubConnection connection)
{
    return connection;
}

إشعار

تقتصر على أنواع معلمات الربط التي لا تدعم طريقة لتمرير القائمة أو الصفيف، WebPubSubConnection لا يتم دعم بالكامل مع جميع المعلمات التي يحتوي عليها خادم SDK، خاصة roles، ويتضمن groups أيضا و expiresAfter. في حالة احتياج العميل إلى إضافة أدوار أو تأخير إنشاء رمز الوصول المميز في الوظيفة، يقترح العمل مع خادم SDK ل C#‎.

[FunctionName("WebPubSubConnectionCustomRoles")]
public static async Task<Uri> Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequest req)
{
    var serviceClient = new WebPubSubServiceClient(new Uri(endpoint), "<hub>", "<web-pubsub-connection-string>");
    var userId = req.Query["userid"].FirstOrDefault();
    // your method to get custom roles.
    var roles = GetRoles(userId);
    return await serviceClient.GetClientAccessUriAsync(TimeSpan.FromMinutes(5), userId, roles);
}

المثال- WebPubSubContext

يوضح المثال التالي دالة C# التي تحصل على معلومات طلب Web PubSub المصدر باستخدام ربط الإدخال ضمن connect نوع الحدث وإرجاعه عبر HTTP.

[FunctionName("WebPubSubContextInputBinding")]
public static object Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequest req,
    [WebPubSubContext] WebPubSubContext wpsContext)
{
    // in the case request is a preflight or invalid, directly return prebuild response by extension.
    if (wpsContext.IsPreflight || wpsContext.HasError)
    {
        return wpsContext.Response;
    }
    var request = wpsContext.Request as ConnectEventRequest;
    var response = new ConnectEventResponse
    {
        UserId = wpsContext.Request.ConnectionContext.UserId
    };
    return response;
}

التكوين

WebPubSub الاتصال ion

يوضح الجدول التالي خصائص تكوين الربط التي قمت بتعيينها في ملف function.json والسمة WebPubSubConnection .

خاصية function.json خاصية السمة ‏‏الوصف
النوع غير متوفر يجب تعيين إلى webPubSubConnection
الاتجاه غير متوفر يجب تعيين إلى in
الاسم غير متوفر اسم المتغير المستخدم في التعليمات البرمجية للدالة لكائن ربط اتصال الإدخال.
محور المركز مطلوب - يجب تعيين القيمة إلى اسم مركز Web PubSub للدالة التي سيتم تشغيلها. ندعم تعيين القيمة في السمة كأولوية أعلى، أو يمكن تعيينها في إعدادات التطبيق كقيمة عمومية.
المعرف الخاص بالمستخدم معرف المستخدم اختياري - قيمة مطالبة معرف المستخدم التي سيتم تعيينها في الرمز المميز لمفتاح الوصول.
الاتصال Connection مطلوب - اسم إعداد التطبيق الذي يحتوي على خدمة Web PubSub سلسلة الاتصال (افتراضيا إلى "WebPubSub الاتصال ionString").

WebPubSubContext

يوضح الجدول التالي خصائص تكوين الربط التي قمت بتعيينها في ملف functions.json والسمة WebPubSubContext .

خاصية function.json خاصية السمة ‏‏الوصف
النوع غير متوفر يجب تعيينه إلى webPubSubContext.
الاتجاه غير متوفر يجب تعيينه إلى in.
الاسم غير متوفر اسم المتغير المستخدم في التعليمات البرمجية للدالة لإدخال طلب Web PubSub.
الاتصال Connection اختياري - اسم إعدادات التطبيق أو مجموعة الإعدادات التي تحدد خدمة Azure Web PubSub الأولية. يتم استخدام القيمة لحماية إساءة الاستخدام والتحقق من صحة التوقيع. يتم حل القيمة تلقائيا باستخدام "WebPubSub الاتصال ionString" بشكل افتراضي. ويعني null أن التحقق من الصحة غير مطلوب وينجح دائما.

الاستخدام

WebPubSub الاتصال ion

WebPubSubConnection يوفر الخصائص أدناه.

اسم الربط نوع الربط ‏‏الوصف
BaseUri Uri عنوان uri لاتصال عميل Web PubSub.
Uri Uri يحتوي Uri المطلق لاتصال Web PubSub على AccessToken أساس تم إنشاؤه على الطلب.
AccessToken سلسلة تم AccessToken إنشاؤه بناء على طلب UserId ومعلومات الخدمة.

WebPubSubContext

WebPubSubContext يوفر الخصائص أدناه.

اسم الربط نوع الربط ‏‏الوصف خصائص
طلب WebPubSubEventRequest طلب من العميل، راجع الجدول أدناه للحصول على التفاصيل. WebPubSubConnectionContext من عنوان الطلب والخصائص الأخرى التي تم إلغاء تسلسلها من نص الطلب، وصف الطلب، على سبيل المثال، Reason ل DisconnectedEventRequest.
response HttpResponseMessage ينشئ الملحق الاستجابة بشكل أساسي لحالات AbuseProtection الخطأ و. -
errorMessage سلسلة وصف تفاصيل الخطأ عند معالجة طلب المصدر. -
hasError منطقي ضع علامة للإشارة إلى ما إذا كان طلب مصدر Web PubSub صالحا. -
isPreflight منطقي ضع علامة للإشارة إلى ما إذا كان طلب الاختبار المبدئي ل AbuseProtection. -

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

الفئة المشتقة ‏‏الوصف خصائص
PreflightRequest يستخدم في AbuseProtection عندما IsPreflight يكون صحيحا -
ConnectEventRequest يستخدم في نوع حدث النظام Connect المطالبات والاستعلام والبروتوكولس الفرعية وClientCertificates
ConnectedEventRequest يستخدم في نوع حدث النظام Connected -
UserEventRequest يستخدم في نوع حدث المستخدم Data, DataType
DisconnectedEventRequest يستخدم في نوع حدث النظام Disconnected السبب

إشعار

WebPubSubContext على الرغم من أن ربط الإدخال يوفر طلب مماثلا لإلغاء تسلسل الطريقة ضمن HttpTrigger مقارنة ب WebPubSubTrigger، هناك قيود، أي أن دمج نشر حالة الاتصال غير مدعوم. لا يزال جانب الخدمة يحترم استجابة الإرجاع، ولكن يحتاج المستخدمون إلى إنشاء الاستجابة بأنفسهم. إذا كان المستخدمون بحاجة إلى تعيين استجابة الحدث، فيجب عليك إرجاع HttpResponseMessage يحتوي على ConnectEventResponse أو رسائل لحدث المستخدم كنصاستجابة ووضع حالة الاتصال مع المفتاح ce-connectionstate في رأس الاستجابة.

ربط بيانات الإخراج

استخدم ربط إخراج Web PubSub لاستدعاء خدمة Azure Web PubSub للقيام بشيء ما. يمكنك بث رسالة إلى:

  • جميع العملاء المتصلين
  • عملاء متصلون تمت مصادقتهم لمستخدم معين
  • العملاء الاتصال انضموا إلى مجموعة معينة
  • اتصال عميل معين

يسمح لك ربط الإخراج أيضا بإدارة العملاء والمجموعات، بالإضافة إلى منح/إبطال الأذونات التي تستهدف connectionId معين مع المجموعة.

  • إضافة اتصال إلى المجموعة
  • إضافة مستخدم إلى المجموعة
  • إزالة الاتصال من مجموعة
  • إزالة مستخدم من مجموعة
  • حذف مستخدم من جميع المجموعات
  • إغلاق كافة اتصالات العميل
  • إغلاق اتصال عميل معين
  • إغلاق الاتصالات في مجموعة
  • منح إذن اتصال
  • إبطال إذن الاتصال

للحصول على معلومات حول تفاصيل الإعداد والتكوين، راجع الاستعراض العام.

مثال

[FunctionName("WebPubSubOutputBinding")]
public static async Task RunAsync(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequest req,
    [WebPubSub(Hub = "<hub>")] IAsyncCollector<WebPubSubAction> actions)
{
    await actions.AddAsync(WebPubSubAction.CreateSendToAllAction("Hello Web PubSub!", WebPubSubDataType.Text));
}

WebPubSubAction

WebPubSubAction هو النوع المجرد الأساسي لروابط الإخراج. تمثل الأنواع المشتقة خادم الإجراء الذي تريد الخدمة استدعاءه.

في لغة C#، نقدم بعض الطرق الثابتة ضمن WebPubSubAction للمساعدة في اكتشاف الإجراءات المتاحة. على سبيل المثال، يمكن للمستخدم إنشاء SendToAllAction عن طريق استدعاء WebPubSubAction.CreateSendToAllAction().

الفئة المشتقة خصائص
SendToAllAction Data, DataType, Excluded
SendToGroupAction المجموعة، البيانات، نوع البيانات، مستبعد
SendToUserAction معرف المستخدم، البيانات، نوع البيانات
SendToConnectionAction الاتصال ionId، والبيانات، وDataType
AddUserToGroupAction معرف المستخدم، المجموعة
RemoveUserFromGroupAction معرف المستخدم، المجموعة
RemoveUserFromAllGroupsAction معرف المستخدم
AddConnectionToGroupAction الاتصال ionId، المجموعة
RemoveConnectionFromGroupAction الاتصال ionId، المجموعة
CloseAllConnectionsAction مستبعد، السبب
CloseClientConnectionAction الاتصال ionId، السبب
CloseGroupConnectionsAction المجموعة، المستبعد، السبب
GrantPermissionAction الاتصال ionId, Permission, TargetName
RevokePermissionAction الاتصال ionId, Permission, TargetName

التكوين

WebPubSub

يوضح الجدول التالي خصائص تكوين الربط التي قمت بتعيينها في ملف function.json والسمة WebPubSub .

خاصية function.json خاصية السمة ‏‏الوصف
النوع غير متوفر يجب تعيين إلى webPubSub
الاتجاه غير متوفر يجب تعيين إلى out
الاسم غير متوفر اسم المتغير المستخدم في التعليمات البرمجية للدالة لكائن ربط الإخراج.
محور المركز يجب تعيين القيمة إلى اسم مركز Web PubSub للدالة التي سيتم تشغيلها. ندعم تعيين القيمة في السمة كأولوية أعلى، أو يمكن تعيينها في إعدادات التطبيق كقيمة عمومية.
الاتصال Connection اسم إعداد التطبيق الذي يحتوي على سلسلة الاتصال خدمة Web PubSub (افتراضيا إلى "WebPubSub الاتصال ionString").

استكشاف الأخطاء وإصلاحها

إعداد تسجيل وحدة التحكم

يمكنك أيضا تمكين تسجيل وحدة التحكم بسهولة إذا كنت تريد التعمق في الطلبات التي تقوم بها مقابل الخدمة.

الخطوات التالية

استخدم هذه الموارد لبدء إنشاء التطبيق الخاص بك: