أجهزة الكمبيوتر شبابيك إنترنت

مآخذ جافا سكريبت وخادم PHP. مآخذ في PHP. استخدام WebSocket مع phpws. متى يجب تجنب استخدام WebSockets

أو البدء باستخدام WebSocket PHP بدون phpDaemon

مرحبًا! آسف لهذا العنوان الطويل، لكني آمل أن يكون العثور على هذه المقالة أسهل للمبتدئين مثلي، لأنني لم أتمكن من العثور على شيء مثلها. قبل بضعة أسابيع، قررت إعادة صياغة عميل اللعبة وخادم لعبتي Growing Crystals مع AJAX، على WebSocket، ولكن تبين أن كل شيء لم يكن صعبًا فحسب، بل كان صعبًا للغاية. لهذا السبب قررت أن أكتب مقالًا من شأنه أن يساعد معظم مطوري WebSocket + PHP المبتدئين على توفير عدة أيام من الوقت من خلال شرح كل خطوة بأكبر قدر ممكن من التفاصيل في إعداد وتشغيل أول برنامج نصي WebSocket في PHP.

لن أقدم الكود الخاص بخادم المقبس في PHP، لأن... إنه موجود في الأرشيف ومزود بالتعليقات. لقد حددت وقت تشغيل قبول الاتصالات بشكل مصطنع بـ 100 ثانية حتى لا يبقى البرنامج النصي في الذاكرة، ويغلق جميع الاتصالات، ولن يضطر إلى إعادة تشغيل Denver باستمرار عند إجراء تغييرات عليه. علاوة على ذلك، بعد 100 ثانية، لن يتوقف البرنامج النصي عن العمل، بل سينتظر الاتصال، وبعد ذلك سيتم الانتهاء من عمله وسيتم إغلاق جميع المقابس بأمان. أيضًا، للاختبار، أستخدم المضيف المحلي والمنفذ 889.

المقبس_bind($socket, "127.0.0.1", 889);// ربطه بعنوان IP والمنفذ المحددين

يمكن وضع الملفات من الأرشيف في المجلد الجذر للمضيف المحلي في دنفر. خوارزمية الاختبار:

  1. نطلق http://localhost/socket.html، وسوف يتصل تلقائيًا بخادم صدى ws ws://echo.websocket.org، ويمكنك إرسال العديد من الرسائل التي يجب على الخادم إرسالها مرة أخرى، لأن هذا خادم صدى. إذا نجح الأمر، فهذا رائع، فكل شيء على ما يرام مع العميل، وإذا لم يكن الأمر كذلك، فتحقق مما إذا كنت قد وضعت جميع الملفات في دليل واحد، وإذا كان لديك Denver قيد التشغيل، وإذا كان لديك اتصال بالإنترنت.
  2. افتح وحدة تحكم JavaScript في نفس علامة التبويب حيث يكون عميل ws مفتوحًا (في GoogleChrome 34.8.1847.137 m وفي FireFox، يتم ذلك تقريبًا بنفس القائمة->tools->Java Script console أو Ctrl+Shift+J، ولكن شخصيًا أنا استخدمه لوحدة تحكم FireBug هذه). إرسال عدد قليل من الرسائل. سترى الرسائل القادمة من الخادم. يمكنك النقر فوق قطع الاتصال ثم إرسال عدة رسائل، وسوف تتأكد من أن الرسائل لا تختفي، لأن. تم قطع الاتصال بخادم ws://echo.websocket.org.
  3. أطلقنا خادمنا المقبس http://localhost/simpleworking.php في علامة تبويب متصفح جديدة. من المرغوب فيه أن تتمكن على الفور من رؤية علامة تبويب العميل مع وحدة التحكم وعلامة تبويب الخادم. GO() ... مقبس_إنشاء ... موافق مقبس_ربط ... موافق مقبس الاستماع ... موافق

    مما يعني أن الخادم جاهز للاتصالات الواردة.

  4. في علامة تبويب العميل، في حقل عنوان الخادم، أدخل ws://127.0.0.1:889 وانقر فوق إعادة الاتصال، نرى أنه لا يحدث أي شيء على العميل، ولكن رسائل مثل العميل "معرف المورد #3" قد تم توصيلها بإرسال إلى العميل " مرحبًا" تظهر على الخادم، أيها العميل!"... حسنًا في انتظار... حسنًا

    مما يخبرنا أنه من الناحية الفنية تم إنشاء اتصال بالمقبس الموجود على الخادم، ولكن من المتوقع وجود اتصال عبر بروتوكول مقبس الويب على العميل، ولم يتم تأسيسه، لأنه لم يتلق المتصفح رؤوس بروتوكول ws المناسبة. عند محاولة إرسال رسالة من العميل، يجب أن يظهر خطأ في وحدة التحكم يشير إلى أنه لم يتم تأسيس الاتصال بـ ws. لسوء الحظ، سيتوقف البرنامج النصي في GoolgeChrome، وبالنسبة لمحاولات الاتصال الجديدة، سيتعين عليك إعادة تحميل الصفحة باستخدام عميل الويب. في FireFox يستمر تشغيل البرنامج النصي. تأكد من إعادة الاتصال بعد 100 ثانية من تشغيل البرنامج النصي للخادم للسماح بإكماله بنجاح.

    تم توصيل العميل "معرف المورد #4" أرسل إلى العميل "مرحبًا، العميل!"... الوقت المناسب = 309.8900001049return go() انتهى إغلاق الاتصال... حسنًا

  5. للتأكد أخيرًا من استجابة الخادم وعدم حظر رسائله بواسطة جدار الحماية، قم بتشغيل البرنامج النصي للخادم http://localhost/simpleworking.php، وابدأ تشغيل telnet وحاول الاتصال بـ 127.0.0.1:889، ولكن يجب أن يكون هذا يتم ذلك في موعد لا يتجاوز 100 ثانية، من لحظة بدء تشغيل الخادم حتى إغلاق الاتصالات وإكمال البرنامج النصي.

يجب أن تأتي الاستجابة "مرحبًا أيها العميل!" عبر telnet، مما يشير إلى أن كل شيء يعمل بشكل طبيعي وأن الاتصال بالخادم ثنائي الاتجاه.

عند الاختبار على جهاز كمبيوتر محلي باستخدام Denver، تأكد دائمًا من اكتمال البرنامج النصي PHP، وإلا قم بإعادة تشغيل Denver لتجنب الاصطدامات والمنافذ المزدحمة.

بروتوكول ويبسوكيت

الآن كل ما تبقى هو تعليم خادم مأخذ التوصيل الخاص بنا كيفية التواصل مثل خادم مقبس الويب، والعمل بشكل صحيح في الخلفية (البرنامج الخفي)، والأهم من ذلك، على استضافة رخيصة. القليل من النظرية: السماح للخادم بعرض الرسالة التي نتلقاها من العميل عند محاولة الاتصال، وإضافة $msg = "Hello, Client!" قبل السطر؛ شفرة

يقول صدى "العميل \"".$accept."\":

";
صدى المقبس_قراءة($قبول,512);
صدى صوت "
";

يمكنك أن ترى أن محاولة إنشاء اتصال باستخدام بروتوكول WebSocket تكون دائمًا مصحوبة بإرسال العميل رأسًا يتوافق بشكل إلزامي مع تنسيق بروتوكول WebSocket. لم يتم اختيار العلامة المسبقة لعرض الرؤوس عن طريق الصدفة، لأنه في العناوين، تلعب فواصل الأسطر دورًا كبيرًا. هذه هي الرؤوس التي أحصل عليها من المتصفحات عندما أحاول الاتصال بموقعنا ws://127.0.0.1:889.

GET / HTTP/1.1 المضيف: المضيف المحلي: 889 وكيل المستخدم: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0 قبول: text/html,application/xhtml+xml,application/xml; q=0.9,*/*;q=0.8 لغة القبول: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3 قبول التشفير: gzip, deflate Sec-WebSocket-Version : 13 الأصل: http://localhost Sec-WebSocket-Key: ndHtpnSPk2H0qOeP6ry46A== ملف تعريف الارتباط: vc=3; __gads=ID=9eabc58c385071c7:T=1400699204:S=ALNI_Ma_g9PZBXpi_MLKDBsao3LQiGx-EA الاتصال: استمرار التشغيل، براغما الترقية:

الحصول على / HTTP/1.1 الترقية: اتصال websocket: ترقية المضيف: المضيف المحلي: 889 الأصل: http://localhost Pragma: no-cache Cache-Control: no-cache Sec-WebSocket-Key: zNMTfmc+C9UK6Ztmv4cE5g== Sec-WebSocket- الإصدار: 13 ثانية - ملحقات WebSocket: تفريغ الرسالة؛ Client_max_window_bits، x-webkit-deflate-frame وكيل المستخدم: Mozilla/5.0 (Windows NT 6.1؛ WOW64) AppleWebKit/537.36 (KHTML، مثل Gecko) Chrome/35.0.1916.114 Safari/537.36

حتى قبل أن أبدأ في تعلم مقابس الويب، اعتقدت أن العمل مع مآخذ الويب سيكون مشابهًا للعمل مع AJAX، حيث أرسلنا طلبات إلى الخادم باستخدام JavaScript XMLHttpRequest()، ولكن في الواقع تبين أن المهمة أكثر تعقيدًا، و أولاً وقبل كل شيء، لأن WebSocket هو بروتوكول على نفس مستوى بروتوكول HTTP (ولكن مع بعض الفروق الدقيقة) في نموذج شبكة OSI، مما يعني أنه من جانب الخادم نحتاج إلى تنفيذ وظائف مشابهة لمعالجة HTTP (وهو ما قام به Apache دائمًا ). استمرارًا للمقارنات مع AJAX، في AJAX لا نحتاج إلى توفير بروتوكول HTTP لأنه يتم كل ذلك بواسطة متصفح Apache وخادم الويب. نحن ببساطة نرسل ونستقبل الرسائل. ولكن على الرغم من أن استخدام WS يفرض علينا قدرًا كبيرًا من العمل المرتبط بتنفيذ خادم في PHP، إلا أنه يوفر أيضًا مزايا: تقليل كمية البيانات المنقولة وزيادة أداء برنامج الخادم. للتواصل بنجاح مع العملاء عبر بروتوكول WebSocket، يجب أن يلتزم الخادم بشكل صارم بمتطلبات معيار RFC6455، الذي يصف بالتفصيل تنسيقات رؤوس الاستجابة. يمكن تقسيم جميع الرسائل المرسلة عبر بروتوكول WebSocket إلى عدة أنواع: المصافحة (المصافحة عند إنشاء اتصال)، بينج بونج (التحقق من الاتصال) ونقل البيانات (نقل البيانات). يوجد أيضًا وصف أقصر للبروتوكول بشكل عام باللغة الروسية. من أجل ضمان الاتصال الكامل والصحيح بين الخادم والعميل عبر بروتوكول مقبس الويب، من الضروري تنفيذ وظائف في PHP لتلقي وتحليل الرؤوس من العميل، وتجميع الرؤوس بواسطة الخادم، وتجميع المفتاح، والرقم من الآخرين. بعد دراسة المواد المقدمة على حبري والموارد الأخرى، تمكنا من العثور على وظائف مناسبة تم تنفيذها، والفرق الوحيد المربك هو أن معظم المؤلفين يستخدمون وظائف الدفق للعمل مع المقابس، فهي تعتبر أكثر إحكاما، ولكن في نفس الوقت أكثر كثافة في استخدام الموارد بسبب استخدام المخزن المؤقت. للتبديل إلى وظائف الدفق للعمل مع المقابس، لا تحتاج إلى تثبيت أي وحدات إضافية غير تلك المثبتة بالفعل، لأن يتم إنشاء سلاسل الرسائل في PHP 5 افتراضيًا. تبدأ وظائف مأخذ التوصيل دائمًا بـstream_socket_*. عند استخدام وظائف الدفق، فمن المستحسن التأكد من أن phpinfo() يدعم النقل المطلوب للتدفقات.

عمليات نقل مأخذ التوصيل المسجلة: tcp، udp.

إذا لم تكن هناك مثل هذه المعلومات في phpinfo() أو إذا ظهرت مشكلات أخرى، فيرجى الرجوع إلى الوثائق، ولكن يمكن حل المشكلة ببساطة عن طريق تحديث Denver إلى الإصدار الأحدث.
حقيقة أخرى مهمة هي أن معظم الأنظمة تحد من القدرة على إنشاء مأخذ توصيل على منفذ أقل من 1024، لذلك سيتم استخدام منفذ المقبس 8889 في جميع البرامج الإضافية.
باستخدام أكواد المصدر لوظائف تشفير وفك تشفير رؤوس بروتوكول WebSocket كأساس، تمكنا من تنفيذ خادم صدى ws كامل. خوارزمية تشغيله بسيطة كما في الحالة السابقة: نقوم بإنشاء خادم ws باستخدام وظيفةstream_socket_server، وتشغيل حلقة لا نهاية لها نتحقق فيها من الاتصالات الجديدة، وعندما نتلقى اتصالًا جديدًا، نضعه في $connects قم أيضًا بتشغيل حلقة ثانية تمر عبر جميع الاتصالات وتغلق الاتصالات الفاشلة وتستقبل الرسائل من الاتصالات المفتوحة. أضفت أيضًا ثلاث وظائف إلى برنامج PHP النصي، والتي صممتها كمعالجات للأحداث.

الدالة عند الفتح($connect, $info) (
صدى "افتح موافق
\ن"؛
}

وظيفة onClose($connect) (
صدى "أغلق موافق
\ن"؛
}

وظيفة onMessage($connect, $data) (
$f = فك التشفير($data);
صدى "الرسالة:";
صدى $f["الحمولة"] . "
\ن"؛
fwrite($connect, encode($f["payload"]));
}

والتي لا تفعل شيئًا سوى عرض رسائل الأحداث على الشاشة. وعندما نتلقى رسالة من العميل، نقوم بفك تشفيرها وإرسال نصها مرة أخرى بعد تشفيره مسبقًا. ، لم يتغير عميل WS. يمكنك اختبار خادم صدى ws عن طريق تنزيل الأرشيف ووضعه في المجلد الجذر للمضيف المحلي في Denver. قم بتوصيل العميل بالعنوان ws://127.0.0.1:8889.
سنناقش التفاصيل الدقيقة المرتبطة بتشغيل خادم ws في الخلفية (البرنامج الخفي)، وتشغيله على استضافة. سأكون سعيدًا لتلقي التعليقات والتعليقات.

وخاصة بالنسبة لأولئك الذين يبحثون عن استضافة لتشغيل مشروعك على مآخذ الويبمناقشة .

مقالاتي حول شياطين PHP ومآخذ الويب

  • مقبس ويب بسيط في PHP أو مآخذ ويب مع 0 مطلق

مآخذ الويب

تعد أحداث الخادم، التي تمت مناقشتها سابقًا، أداة مثالية عندما تحتاج إلى تلقي سلسلة من الرسائل من خادم الويب. لكن تبين أن الاتصال من جانب واحد تمامًا. لا يمكن للمتصفح الرد على الرسائل أو الدخول في حوار أكثر تعقيدًا مع الخادم.

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

أولاً، كائن XMLHttpRequest ليس مناسبًا تمامًا لتبادل رسائل متعددة بسرعة (على سبيل المثال، في الدردشة). ومن ثم، لا توجد طريقة لربط مكالمة بأخرى، لذلك مع كل طلب جديد من صفحة ويب، يجب على الخادم معرفة من البداية لمن تنتمي هذه الصفحة. ولذلك، فإن مستوى تعقيد التعليمات البرمجية للتعامل مع سلسلة من الطلبات ذات الصلة من صفحة الويب يمكن أن ينمو بسرعة كبيرة إلى حد أنه من المستحيل تنفيذه عمليًا.

هناك حل لجميع هذه المشاكل، على الرغم من أنه ليس جاهزا تماما بعد. هذا الحل هو التكنولوجيا مآخذ الويب، والذي يسمح للمتصفح بالحفاظ على اتصال مفتوح بالخادم وتبادل الرسائل لأي مقدار من الوقت المطلوب.

لقد أثارت تقنية Websocket الكثير من الإثارة بين مطوري الويب، لكنها لا تزال في طور التطوير، على الرغم من أنها تتمتع بالفعل بتوافق جيد مع المتصفح:

في الوقت الحالي، من الأفضل اختبار الصفحات التي تستخدم websockets في متصفح Chrome، والذي يوفر الدعم الأكثر اتساقًا لها.

الوصول إلى websockets

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

يمكن أن تكون حلول Websocket معقدة للغاية. سيكون تطوير كود JavaScript لصفحة واحدة مهمة بسيطة إلى حد ما. ولكن لإنشاء تطبيق خادم، ستحتاج إلى قدر كبير من المعرفة والمهارات البرمجية، بما في ذلك فهم مفاهيم تعدد مؤشرات الترابط والشبكات.

لاستخدام websockets، يجب أن يقوم خادم الويب الخاص بموقعك بتشغيل برنامج خاص، والذي من المتوقع أن يسمى خادم websocket. هذا البرنامج مسؤول عن تنسيق تفاعل جميع المشاركين، وبمجرد إطلاقه فإنه يعمل دون توقف.

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

لإعطائك فكرة عن نطاق خادم websocket، فكر في بعض المهام التي يجب أن يؤديها خادم المقبس:

    تجميع "قاموس" للرسائل، بمعنى آخر، تحديد أنواع الرسائل المقبولة وأيها غير مقبولة؛

    تحديد الأخطاء عند إرسال الرسائل إلى العملاء والتوقف عن محاولة الاتصال بهم إذا بدا أنها لم تعد موجودة؛

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

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

هناك طريقة أخرى تتمثل في أخذ رمز خادم websocket الخاص بشخص آخر وتخصيصه وفقًا لمتطلباتك. حاليًا، هناك عدد كبير جدًا من المشاريع (العديد منها مجانية ومفتوحة المصدر) تعمل على تطوير خوادم مقبس الويب لحل المشكلات المختلفة، بلغات برمجة الخوادم المختلفة.

عميل websocket بسيط

من منظور صفحة الويب، من السهل فهم واستخدام وظيفة websocket. الخطوة الأولى هي الإنشاء كائن WebSocketوتمرير عنوان URL إليه. الكود الخاص بهذا مشابه لما يلي:

var المقبس = new WebSocket("ws://localhost/socketServer.php");

تبدأ سلسلة عنوان URL بالنص ws://، الذي يحدد اتصال مقبس الويب. يشير عنوان URL هذا إلى ملف تطبيق الويب الموجود على الخادم (في هذه الحالة البرنامج النصي المقبسocketServer.php).

يدعم معيار Web Switches أيضًا عناوين URL التي تبدأ بالنص wss://، مما يشير إلى ضرورة استخدام اتصال آمن ومشفر (تمامًا كما هو الحال عند طلب صفحة ويب، حدد عنوان URL الذي يبدأ بـ https:// بدلاً من http : //).

يمكن لـ Websockets الاتصال بأكثر من مجرد خادم الويب الخاص بهم. يمكن لصفحة الويب فتح اتصال بخادم مقبس الويب الذي يعمل على خادم ويب آخر دون الحاجة إلى أي جهد إضافي.

إن عملية إنشاء كائن WebSocket تجبر الصفحة على محاولة الاتصال بالخادم. بعد ذلك، تحتاج إلى استخدام أحد الأحداث الأربعة لكائن WebSocket: onOpen(عند إنشاء الاتصال)، خطأ(عند حدوث خطأ) onClose(عند إغلاق الاتصال) و onMessage(عندما تتلقى الصفحة رسالة من الخادم):

المقبس.onopen = ConnectionOpen; المقبس.onmessage = messageReceived; المقبس.onerror = errorOccurred; المقبس.onopen = ConnectionClosed;

على سبيل المثال، إذا كان الاتصال ناجحًا، فسيكون من الجيد إرسال رسالة تأكيد مقابلة. يتم تسليم هذه الرسالة باستخدام الطريقة يرسل()كائن WebSocket الذي يتم تمريره بنص عادي كمعلمة. فيما يلي دالة تتعامل مع حدث onopen وترسل رسالة:

اتصال الوظيفةOpen() (socket.send("اسم المستخدم: [البريد الإلكتروني محمي]"); }

من المفترض أن يتلقى خادم الويب هذه الرسالة ويستجيب لها.

يمكن استخدام الأحداث onError وonClose لإرسال إشعارات إلى زائر صفحة الويب. ولكن الأهم على الإطلاق هو حدث onMessage، الذي يتم تشغيله عند تلقي بيانات جديدة من الخادم. مرة أخرى، يعد كود JavaScript للتعامل مع هذا الحدث أمرًا مباشرًا - فنحن ببساطة نسترد نص الرسالة من خاصية البيانات:

الوظيفة messageReceived(e) ( messageLog.innerHTML += "

إذا قررت صفحة الويب أن جميع أعمالها قد تم إنجازها، فيمكنها إغلاق الاتصال باستخدام هذه الطريقة قطع الاتصال():

قطع الاتصال();

من هذه النظرة العامة على websockets، يمكننا أن نرى أن استخدام خادم websocket لجهة خارجية هو أمر بسيط - نحتاج فقط إلى معرفة الرسائل التي يجب إرسالها والرسائل التي يجب انتظارها.

هناك الكثير من العمل الذي تم إنجازه خلف الكواليس لجعل اتصالات websocket تعمل. أولاً، تتصل صفحة الويب باستخدام معيار HTTP العادي. يحتاج هذا الاتصال بعد ذلك إلى الترقية إلى اتصال websocket، مما يسمح بالاتصال المجاني ثنائي الاتجاه. قد تكون هناك مشاكل في هذه المرحلة إذا كان هناك خادم وكيل بين كمبيوتر العميل وخادم الويب (كما هو الحال، على سبيل المثال، في شبكة الشركة النموذجية). قد يرفض الخادم الوكيل التعاون وسيقوم بإنهاء الاتصال. يمكن حل هذه المشكلة عن طريق الكشف عن فشل الاتصال (عبر حدث onError الخاص بكائن WebSocket) وتطبيق إحدى عمليات تعبئة المقبس المتعددة الموضحة على موقع GitHub. تستخدم هذه العناصر النائبة طريقة استقصاء لمحاكاة اتصال websocket.

أمثلة على websockets على شبكة الإنترنت

إذا كنت مهتمًا بتجربة websockets، فهناك العديد من المواقع عبر الإنترنت حيث يمكنك بدء التطوير.

للبدء، جرب websocket.org، الذي يوفر خادم websocket بسيط: ترسل صفحة الويب رسالة إليها، وتقوم بإرجاع نفس الرسالة إلى صفحة الويب:

على الرغم من أن خادم websocket هذا ليس شيئًا خاصًا، إلا أنه يسمح لك بتجربة جميع ميزات كائن WebSocket. علاوة على ذلك، يمكنك الاتصال بهذا الخادم من صفحة موجودة على كل من خادم الويب الخاص بالإنتاج وخادم الويب الاختباري على جهاز الكمبيوتر الخاص بك، أو حتى من الصفحة التي يتم تشغيلها ببساطة من محرك الأقراص الثابتة لديك:

var المقبس = new WebSocket("ws://echo.websocket.org"); المقبس.onopen = ConnectionOpen; المقبس.onmessage = messageReceived; اتصال الوظيفةOpen() (socket.send("اسم المستخدم: [البريد الإلكتروني محمي]"); ) وظيفة messageReceived(e) ( var messageLog = document.getElementById("messageLog"); messageLog.innerHTML += "
" + "استجابة الخادم: " + e.data; )

هناك أيضًا خوادم websocket التي توفر إمكانات أخرى، بما في ذلك ما يلي.

في هذه المقالة، سننظر في العمل مع مكتبة phpws، اللازمة لتنظيم التطبيقات أو تطبيقات الويب بناءً على المقابس وتشغيل بضعة أمثلة قياسية معروضة على صفحة مستودع GitHub لهذا المشروع.

ملحوظة. ستعمل مآخذنا على جانب الخادم وعلى جانب العميل. على جانب الخادم، سيتم تنفيذ ذلك بواسطة WebSocket القياسي، الذي ظهر بتنسيق HTML5، وسيتم تنفيذ العمل على جانب الخادم، حيث لدينا PHP، بواسطة مكتبة phpws. هناك العديد من المكتبات المشابهة ولعل أبرزها Ratchet التي بدت مرهقة بالنسبة لي لمشروعي الصغير واستقريت على phpws.

نحن بحاجة إلى الملحن

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

$ الضفيرة -s https://getcomposer.org/installer | بي أتش بي

لقد قمنا بتنزيله، ولكن لن يتم تنفيذ أوامر الملحن عبر PATH، لذلك سنقوم بنقل الملف الذي تم تنزيله إلى /usr/local/bin

$ mv Composer.phar /usr/local/bin/composer

نقوم بتنفيذ الأمر ونحصل على النتيجة في شكل تعليمات وأوامر الملحن، مما يدل على التثبيت الناجح

$ الملحن

بالنسبة لنظامي التشغيل Windows وMac، يمكنك الاطلاع على التعليمات الموجودة خارج الموقع.

ملحوظة. يجب تحديد جميع التبعيات التي يجب تضمينها في ملف Composer.json في جذر المشروع، والذي سيقوم بتنزيل وتحديث وجمع كل التبعيات في مجلد بائع واحد، والذي يمكن بعد ذلك تحميله عبر أداة التحميل التلقائي للفئة. يمتلك Composer مستودعًا خاصًا به من الحزم والمكتبات يسمى Packagist، والذي يسمح لك بتحديد البائع/الحزمة وسيتم تثبيته. نعم، يمكنك تحديد عناوين محددة لمستودعات svn/git في Composer.json، لكن هذا غير مناسب. من الملائم أكثر أن يكون لديك نوع من النقطة المركزية حيث توجد حزم متطابقة مع عناوين المستودع الخاصة بها. هذا هو Packagist.

نحن بحاجة إلى مكتبة phpws

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

( "المستودعات": [( "النوع": "vcs"، "url": "https://github.com/Devristo/phpws" ) ]، "تتطلب": ( "devristo/phpws": "dev-master " ) )

في هذه الحالة، أشرنا إلى إمكانية التنزيل مباشرة من مستودع GitHub دون وساطة Packagist.

لننفذ هذا الملف باستخدام الأمر

تثبيت الملحن $

بعد ذلك، سيظهر مجلد فرعي للمورد يحتوي على المكتبات التي تم تنزيلها في المجلد وكل ما يتعين علينا فعله هو الاتصال بها واستخدامها.

نحن بحاجة إلى فهم أساسي لكيفية عمل WebSocket مع PHP

وهكذا، لمدة دقيقة، دعونا نتعرف على ما يجب فعله بالمكتبات التي تم تنزيلها وكيفية استخدامها، ولن أتعمق في الأمر، لذلك إذا كان الأمر في متناول اليد، فسنحتاج إلى ملفين:

  1. Client.html هو الملف من جانب العميل الذي يراه الشخص الذي يقف خلف المتصفح. ويستخدم جافا سكريبت للعمل مع المقبس.
  2. server.php هو في الواقع خادم المقبس الخاص بنا، والذي يعالج جميع الطلبات الواردة من العميل ويستجيب لها باستجابات تمت معالجتها.

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

بالنسبة للجزء العميل:

مقبس فار = "ws://127.0.0.0:12345/";

بالنسبة لجزء الخادم:

$server = new WebSocketServer("tcp://127.0.0.0:12345", $loop, $logger);

مثال قياسي لعرض وقت الخادم الحالي، محدثًا للثاني

لكي يعمل هذا المثال، تحتاج إلى تشغيل ملف server.php مرة واحدة من خلال وحدة التحكم وبعد تنفيذ هذا البرنامج النصي، قم بتشغيل خادم المقبس بمعرف PID الخاص به

ماذا يفعل المثال؟ يوضح المثال كيف يقوم المقبس، بما يصل إلى جزء من الثانية، بتحديث معلومات الوقت إلى الخادم وإصدارها إلى العميل

جزء العميل:

الموقتات

وقت الخادم

حالة:
وقت:


var المقبس = new WebSocket("ws://localhost:12345"); المقبس.onopen = function(msg)( document.getElementById("status").innerHTML = "Online"; ); مأخذ التوصيل = وظيفة(msg)( document.getElementById("status").innerHTML = "غير متصل"; ) المقبس.onmessage = وظيفة(msg)( document.getElementById("time").innerHTML = msg.data; ) ;

جزء الخادم:

#!/php -qaddWriter($writer); // أنشئ خادم WebSocket باستخدام SSL $server = new WebSocketServer("tcp://127.0.0.0:12345", $loop, $logger); // كل 0.5 ثانية ترسل الوقت إلى كافة العملاء المتصلين $loop->addPeriodicTimer(0.5, function() use($server, $logger)( $time = new DateTime(); $string = $time->format(" Y-m-d H:i:s"); $logger->notice("وقت البث لجميع العملاء: $string"); foreach($server->getConnections() as $client) $client->sendString($string); )); // ربط الخادم $server->bind(); // ابدأ حلقة الحدث $loop->run();

مثال قياسي لمحادثة بسيطة

يظهر مثال على محادثة بسيطة. بصريا يبدو كما في الصورة

جزء العميل:

اختبار ويب سوكيت

اختبار ويب سوكيت

سوف يردد الخادم ردك!


مقبس فار؛ وظيفة createSocket(host) (إذا ("WebSocket" في النافذة) قم بإرجاع WebSocket (host) جديد؛ وإلا إذا ("MozWebSocket" في النافذة) قم بإرجاع MozWebSocket (host) جديد؛ قم برمي خطأ جديد ("لا يوجد دعم لمقبس الويب في المتصفح!") ); ) وظيفة init() ( var host = "ws://127.0.0.0:12345/chat"; حاول ( المقبس = createSocket(host); سجل("WebSocket - الحالة " + المقبس.readyState); المقبس.onopen = وظيفة(msg) (سجل("مرحبا - الحالة" + this.readyState); ); المقبس.onmessage = وظيفة(msg) (سجل(msg.data); ); "غير متصل - الحالة " + this.readyState); ); ) التقاط (على سبيل المثال) ( سجل (على سبيل المثال); ) document.getElementById("msg").focus(); ) وظيفة إرسال () ( var msg = document.getElementById ("msg").value؛ حاول (socket.send(msg); ) Catch (ex) ( log(ex); ) ) وظيفة إنهاء() ( log("وداعا!"); المقبس.إغلاق(); المقبس = null; ) سجل الوظيفة(msg) ( document.getElementById("log").innerHTML += "
" + msg; ) الدالة onkey(event) ( if (event.keyCode == 13) ( send(); ) )

جزء الخادم:

#!/php -q php chat.php use Devristo\Phpws\Framing\WebSocketFrame; استخدم Devristo\Phpws\Framing\WebSocketOpcode؛ استخدم Devristo\Phpws\Messaging\WebSocketMessageInterface; استخدم Devristo\Phpws\Protocol\WebSocketTransportInterface; استخدم Devristo\Phpws\Server\IWebSocketServerObserver؛ استخدم Devristo\Phpws\Server\UriHandler\WebSocketUriHandler; استخدم Devristo\Phpws\Server\WebSocketServer؛ /** * سوف يستجيب معالج ChatHandler أدناه لجميع الرسائل المرسلة إلى /chat (على سبيل المثال ws://localhost:12345/chat) */ class ChatHandler Extends WebSocketUriHandler ( /** * إعلام الجميع عند انضمام مستخدم إلى الدردشة * * @param WebSocketTransportInterface $user */ public function onConnect(WebSocketTransportInterface $user)( foreach($this->getConnections() as $client)( $client->sendString("انضم المستخدم ($user->getId()) إلى chat: "); ) ) /** * بث الرسائل المرسلة من قبل المستخدم إلى كل من في الغرفة * * @param WebSocketTransportInterface $user * @param WebSocketMessageInterface $msg */ public function onMessage(WebSocketTransportInterface $user, WebSocketMessageInterface $msg) ( $this->logger->notice("Broadcasting " . strlen($msg->getData()) . " bytes"); foreach($this->getConnections() as $client)( $client->sendString(" قال المستخدم ($user->getId()): ".$msg->getData()); ) ) ) فئة ChatHandlerForUnroutedUrls تمتد WebSocketUriHandler ( /** * تتعامل هذه الفئة مع المستخدمين الذين لم يتم توجيههم */ public function onConnect( WebSocketTransportInterface $user)( // لا تفعل شيئًا $this->logger->notice("لم ينضم المستخدم ($user->getId()) إلى أي غرفة"); ) وظيفة عامة onMessage(WebSocketTransportInterface $user, WebSocketMessageInterface $msg) ( // لا تفعل شيئًا $this->logger->notice("User ($user->getId()) ليس موجودًا في الغرفة ولكنه حاول أن يقول: ($) msg->getData())"); ) ) $loop = \React\EventLoop\Factory::create(); // أنشئ مسجلاً يكتب كل شيء إلى STDOUT $logger = new \Zend\Log\Logger(); $writer = new Zend\Log\Writer\Stream("php://output"); $logger->addWriter($writer); // إنشاء خادم WebSocket $server = new WebSocketServer("tcp://127.0.0.0:12345", $loop, $logger); // أنشئ جهاز توجيه ينقل كافة اتصالات /الدردشة إلى فئة ChatHandler $router = new \Devristo\Phpws\Server\UriHandler\ClientRouter($server, $logger); // مسار / رابط الدردشة $router->addRoute("#^/chat$#i", new ChatHandler($logger)); // توجيه عناوين URL غير المتطابقة أثناء هذا العرض التوضيحي لتجنب الأخطاء $router->addRoute("#^(.*)$#i", new ChatHandlerForUnroutedUrls($logger)); // ربط الخادم $server->bind(); // ابدأ حلقة الحدث $loop->run();

تحتاج إلى تشغيل هذا المثال مثل المثال السابق - مرة واحدة من خلال وحدة التحكم، قم بتشغيل ملف server.php ومن خلال المتصفح أدخل جزء العميل client.html، الذي يربط البرنامج النصي script.js.

العمل مع PHP - خادم مأخذ التوصيل من وحدة التحكم

من أجل تحديث كود الخادم وإعادة تشغيله، من السهل جدًا استخدام أوامر إيقاف وإعادة تشغيل ملف خادم PHP من خلال وحدة التحكم، وإلا فقد يحدث موقف مؤسف عندما يبدو أنك تقوم بتحرير كود الخادم، ولكنه ينفذ القديم .

أولاً، نعرض معرف العملية (PID) لعملية خادم مأخذ التوصيل قيد التشغيل. نكتشف ذلك من خلال النظر إلى قائمة المقابس العاملة عبر منافذها باستخدام الأمر:

برنامج Netstat --tcp --listening --

بعد العثور على PID المطلوب من القائمة، نقتله باستخدام الأمر:

قتل %pid%

من الناحية المثالية، نقوم بإغلاق WebSocket من خلال جزء JavaScript الخاص بالعميل باستخدام الأمر قبل البدء في "قتل" PID:

المقبس. إغلاق ()؛ المقبس = فارغ؛

ساتيا مكرس لبرمجة الشبكات، وعلى وجه الخصوص برمجة المقبس في PHP. هناك فئتان من وظائف اتصالات الشبكة في PHP:

  1. الوظيفة fsockopen(اسم مضيف السلسلة، منفذ عدد صحيح، رقم خطأ صحيح، وصف خطأ سلسلة، مهلة مزدوجة) - تفتح اتصال الشبكة كتدفق ملف وترجع واصف الملف الذي تعمل به وظائف fputs وfgets وما إلى ذلك.
  2. الوظائف التي تنقل المعلومات مباشرة على مستوى بروتوكول IP. وهذا مستوى أقل بكثير من المستوى الذي تعمل فيه الدالة fsockopen.

سيتم النظر في الوظائف رقم 2 فقط، لأن هم أكثر إثارة للاهتمام.
أولاً، دعونا نتحقق مما إذا كانت مكتبة المقابس متصلة أم لا.

يمكنك التحقق من ذلك باستخدام البرنامج النصي التالي:

إذا (extension_loaded("sockets")) echo "تم تحميل الامتداد"; آخر صدى "لم يتم تحميل الامتداد"؛ ?>

إذا لم يتم تنزيل الامتداد، فيجب عليك تنزيله.

لذا. أبسط مثال في هذه المقالة هو خادم الصدى. خادم الصدى - وهذا يعني أن السلسلة التي أرسلها العميل إلى الخادم يتم إرجاعها مرة أخرى. أي أن الخادم يتلقى بعض الرسائل من العميل، ويفعل شيئًا بها ويرسلها إليه مرة أخرى.

سيكون لدينا نصين:

  1. الخادم أو الشيطان.
  2. عميل.

البرنامج النصي "العميل".

لتنفيذ العميل، نحتاج إلى الوظائف التالية التي تعمل مع المقابس:

  1. المقبس_إنشاء(عائلة عدد صحيح، نوع مقبس عدد صحيح، بروتوكول عدد صحيح)؛ - تقوم الوظيفة بإنشاء مأخذ توصيل وإرجاع مورد المقبس. الوسيط الأول هو عائلة البروتوكول، إذا كان الاتصال عبر الإنترنت، فيجب أن تكون القيمة المحددة - AF_INET؛ إذا كان سيتم الاتصال عبر مآخذ توصيل UNIX - AF_UNIX؛ الوسيطة الثانية هي نوع المقبس. عادةً ما يتم استخدام SOCK_STREAM لاتصالات TCP وSOCK_DGRAM لاتصالات UPD. تحدد الوسيطة الثالثة البروتوكول SOL_TCP أو SOL_UPD حسب النوع.
  2. المقبس_الاتصال(مقبس المورد، عنوان السلسلة، منفذ عدد صحيح)؛ - بعد إنشاء المقبس، يجب عليك الاتصال به. الوسيطة الأولى هي مورد المقبس الذي تم إنشاؤه، والثانية هي عنوان IP للمقبس إذا كانت عائلة البروتوكول هي AF_INET، أو اسم مسار مأخذ توصيل مجال Unix إذا كان المقبس من عائلة AF_UNIX. الوسيطة الثالثة هي رقم المنفذ الذي يجب إنشاء الاتصال به.
  3. المقبس_قراءة(مقبس المورد، طول عدد صحيح، نوع عدد صحيح)؛ - تقرأ الدالة عدد البايتات المحددة في وسيطة الطول من المقبس المحدد. افتراضيًا، تتم القراءة دون أخذ أحرف التحكم في الاعتبار، أو يمكنك تعيين وسيطة النوع إلى PHP_BINARY_READ؛ ولأخذ أحرف التحكم في الاعتبار، يجب عليك تعيين القيمة PHP_NORMAL_READ.
  4. المقبس_الكتابة(مقبس المورد، المخزن المؤقت للسلسلة، طول عدد صحيح)؛ — تقوم الوظيفة بكتابة البيانات إلى المقبس.
  5. المقبس_إغلاق(مقبس الموارد)؛ — يغلق المقبس ويحرر الذاكرة.

القائمة 1.0 - العميل

Set_time_limit(0); ob_implicit_flush(); صدى "- العميل

"; $address = "127.0.0.1"; // عنوان المضيف المحلي. $port = 5555; // المنفذ الذي سيتم إنشاء الاتصال به. echo "إنشاء مأخذ توصيل..."; $socket =ocket_create(AF_INET, SOCK_STREAM) ، SOL_TCP) ؛ إذا ($socket "؛ ) آخر ( echo "OK
"; ) echo "الاتصال بمقبس..."; $connect = المقبس_connect($socket, $address, $port); if($connect === false) ( echo "Error: ".socket_strerror(socket_last_error()) ) "
"؛ ) آخر (صدى "حسنًا

"; $msg = "مرحبًا بالخادم!"; echo "أخبر الخادم \"".$msg."\"..."; المقبس_write($socket, $msg, strlen($msg)); echo "موافق
"; echo "قال الخادم: "; $awr = مقبس_قراءة($socket, 1024); echo $awr."
"; $msg = "exit"; echo "أخبر الخادم \"".$msg."\"..."; المقبس_write($socket, $msg, strlen($msg)); echo "OK
"; ) if(isset($socket)) ( echo "إغلاق الاتصال..."; المقبس_إغلاق($socket); صدى "موافق
"; } ?>

البرنامج النصي للخادم.

لتنفيذ الخادم، نحتاج إلى الوظائف التالية التي تعمل مع المقابس:

  1. جميع الوظائف التي تم وصفها أعلاه.
  2. المقبس_ربط(مقبس المورد، عنوان السلسلة، منفذ عدد صحيح)؛ - تربط الوظيفة عنوانًا بمقبس. وسيطة addres هي عنوان IP الخاص بالمقبس إذا كانت عائلة البروتوكول هي AF_INET، أو اسم مسار مأخذ توصيل مجال Unix إذا كان المقبس من عائلة AF_UNIX.
  3. المقبس_الاستماع(مقبس الموارد، تراكم عدد صحيح) - تستمع الوظيفة للاتصالات الواردة إلى المقبس. تقوم الوسيطة الثانية الاختيارية بتعيين الحد الأقصى لحجم قائمة انتظار الطلبات التي تنتظر الاتصال.
  4. المقبس_قبول(مقبس الموارد)؛ - بمجرد إنشاء المقبس وربطه وبدء الاستماع إليه، فإن هذه الوظيفة هي التي تجعل الخادم خادمًا. تقبل الوظيفة الاتصالات الواردة.

القائمة 1.1 - الخادم

Set_time_limit(0); ob_implicit_flush(); صدى "- الخادم

"; $address = "127.0.0.1"; $port = 5555; echo "إنشاء مأخذ توصيل..."; $socket = مقبس_إنشاء(AF_INET, SOCK_STREAM, SOL_TCP); if($socket "; ) آخر ( echo "OK
"; ) echo "ربط مأخذ توصيل..."; $bind =ocket_bind($socket, $address, $port); if($bind "; ) else ( echo "OK
"; ) echo "الاستماع إلى مأخذ توصيل..."; $listen =ocket_listen($socket, 5); if($listen "; ) else ( echo "OK
"; ) بينما(صحيح) ( صدى "في انتظار..."; $accept = مقبس_قبول($socket); إذا($accept "; استراحة; ) آخر (صدى "موافق"
"; ) $msg = "مرحبا، العميل!"; echo "أرسل إلى العميل \"".$msg."\"... "; مقبس الكتابة($accept, $msg, strlen($msg)); echo " نعم
"; while(true) ( ​​​​$awr =ocket_read($accept, 1024); if (false === $awr) (echo "Error: ".socket_strerror(socket_last_error())."
"; فاصل 2; ) else ( if (trim($awr) == "") فاصل; else echo "قال العميل: ".$awr."
"; ) if ($awr == "exit") (socket_ Close($accept); Break 2; ) echo "أخبر العميل \"".$msg."\"... "; مقبس_write($accept, $awr , strlen($awr)); echo "OK
"; ) ) إذا (isset($socket)) (صدى "إغلاق الاتصال..."; مقبس_إغلاق($socket); صدى "موافق
"; } ?>

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

أريد أيضًا أن أشير إلى أن الوظيفة الأكثر فائدة هي:
المقبس_select(قراءة المصفوفة، كتابة المصفوفة، المصفوفة باستثناء، عدد صحيح timeout_thans، عدد صحيح timeout_microthans)؛ - تتحكم الوظيفة في التغييرات التي تحدث على العقد. تبحث PHP عن البيانات الجديدة التي تصل إلى المقابس المحددة في مصفوفة القراءة. تبحث PHP عن الاستعداد لتلقي البيانات على المقابس المحددة في مصفوفة الكتابة. يتحقق PHP من التدفقات المحددة في الوسيطة باستثناء الأخطاء. تحدد المهلات الوقت الذي ستقوم الدالة بعده بإرجاع عدد المقابس التي غيرت حالتها أو FALSE.

لا يمكن الاستغناء عن هذه الوظيفة لمراقبة العملاء المعلقين على المقبس.

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

تحدثت في المقال السابق عنه . نحن معك باستخدام مآخذ التوصيل قمنا بإنشاء خادم في PHP. وفي هذا المقال سنكتب معك العميل في PHP، والذي سيرسل طلبًا إلى الخادم ويتلقى الرد منه.

أحضر رمز العميل في PHP:

header("نوع المحتوى: نص/عادي;"); // سوف نعرض نصًا بسيطًا
set_time_limit(0); // يجب أن يعمل البرنامج النصي باستمرار
ob_implicit_flush(); // يجب أن يتم إخراج كافة الأصداء على الفور
$address = "المضيف المحلي"; // عنوان عمل الخادم
منفذ $ = 1985؛ // منفذ تشغيل الخادم (ويفضل أن يكون منفذًا نادرًا ما يستخدم)
إذا (($socket = المقبس_إنشاء(AF_INET, SOCK_STREAM, SOL_TCP))< 0) {
//AF_INET - عائلة البروتوكول
//SOCK_STREAM - نوع المقبس
//SOL_TCP - البروتوكول
صدى "خطأ في إنشاء مأخذ التوصيل"؛
}
آخر(
صدى "تم إنشاء المقبس\n";
}
نتيجة $ = مقبس_اتصال($socket, $address, $port);
إذا (نتيجة === خطأ) (
صدى "خطأ في الاتصال بالمقبس"؛
) آخر (
echo "تم الاتصال بالمقبس بنجاح\n";
}

echo "رسالة من الخادم: $out.\n";
$msg = "15";

المقبس_الكتابة($socket, $msg, strlen($msg)); // أرسل رسالة إلى الخادم
$خارج = المقبس_قراءة($socket, 1024); // اقرأ الرسالة من الخادم
echo "رسالة من الخادم: $out.\n"; // إخراج رسالة من الخادم
$msg = "خروج"; //أمر إيقاف التشغيل
صدى "رسالة إلى الخادم: $msg\n";
المقبس_الكتابة($socket, $msg, strlen($msg));
صدى "اكتمل الاتصال\n";
// توقف عن العمل مع المقبس
إذا (إيسيت($socket)) (
المقبس_إغلاق($socket);
صدى "تم إغلاق المقبس بنجاح";
}
?>

تم التعليق على الكود جيدًا، لذلك أعتقد أن كل شيء هنا واضح للغاية. خوارزمية العميل تافهة: إنشاء مأخذ توصيل، والاتصال بالخادم، وإرسال الطلبات، وتلقي الاستجابات، وإغلاق الاتصال. أرسلنا لك الرقم 15 . إذا قرأت المقال السابق، فتذكر أن مهمة الخادم هي تربيع هذا الرقم وإعادته. لذلك، إذا قمت بتشغيل هذا العميل، سوف ترى من الخادم 225 (15*15 ). ثم نعطي الأمر اغلق، مما يوقف الخادم.

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