1. التحليل الافتتاحي
ابتداءً من اليوم ، دعنا نتعلم بالتفصيل في وحدات محددة. هذه المقالة هي المقالة الثالثة في هذه السلسلة. تستند المادتين الأولين بشكل رئيسي إلى النظرية. أعتقد أنه في دراسة المادتين الأولين ،
لدي أيضًا فهم أساسي لـ Nodejs ، لا بأس! ! ! Strike بينما الحديد ساخن ، دعنا نستمر في حمل Nodejs إلى النهاية. حسنًا ، دون أن يقول الكثير من الهراء ، انتقل مباشرة إلى موضوع اليوم "الوحدة النمطية". فكيف يجب أن تفهم "صافي" ذلك؟
ما هو؟ (يمكن استخدام الوحدة Net لإنشاء خوادم المقبس أو عملاء المقبس. والوحدة أساسية لاتصالات بيانات NodeJS هما Net و HTTP. الأول هو تغليف قائم على TCP ، في حين أن الأخير هو طبقة TCP بشكل أساسي ، ولكنها قامت بالكثير من تغليف البيانات ، والتي نعتبرها بمثابة طبقة عرض).
هنا نشير إلى الكود المصدر في Nodejs "http.js":
ليس من الصعب أن نرى من الشكل أن httpserver يرث الفئة الصافية ، وله إمكانيات اتصال ذات صلة ، وقد قامت بمزيد من تغليف البيانات ، والتي نعتبرها طبقة تمثيل أكثر تقدماً.
المعرفة الممتدة (فيما يلي رمز المصدر لـ "الوراثة"):
نسخة الكود كما يلي:
orports.inherits = function (ctor ، superctor) {
ctor.super_ = superctor ؛
ctor.prototype = object.create (superctor.prototype ، {
مُنشئ: {
القيمة: CTOR ،
التعداد: خطأ ،
قابل للكتابة: صحيح ،
قابل للتكوين: صحيح
}
}) ؛
} ؛
الوظيفة هي إدراك الميراث وإعادة الاستخدام.
لقد أعطيت للتو نظرة عامة موجزة ، والتي تحتوي على بعض المفاهيم شائعة الاستخدام. فيما يلي مقدمة موجزة عن تعميم المفاهيم:
(1) بروتوكول TCP/IP ---------- TPC/IP هو بروتوكول طبقة النقل ، والذي يحل بشكل أساسي كيفية نقل البيانات على الشبكة.
(2) ، المقبس --- المقبس هو تغليف وتطبيق بروتوكول TCP/IP (مستوى البرنامج).
(3) ، HTTP ------ HTTP هو بروتوكول طبقة التطبيق ، والذي يحل بشكل أساسي كيفية لف البيانات.
(4) نموذج شبكة سبع طبقة ----------------------------------------------------------------------------------------------------------------------
لتلخيص: المقبس هو تغليف لبروتوكول TCP/IP. المقبس نفسه ليس بروتوكولًا ، بل واجهة استدعاء (API).
هذا يشكل بعضًا من أبسط الواجهات الوظيفية التي نعرفها ، مثل إنشاء ، والاستماع ، والتوصيل ، والقبول ، والقراءة ، والكتابة ، إلخ.
TCP/IP هو مجرد مكدس بروتوكول ، تمامًا مثل آلية تشغيل نظام التشغيل ، يجب تنفيذه بالتفصيل ، ويوفر أيضًا واجهات تشغيل خارجية.
في الواقع ، يعتمد TCP لطبقة النقل على بروتوكول IP لطبقة الشبكة ، ويستند بروتوكول HTTP لطبقة التطبيق على بروتوكول TCP لطبقة النقل. المقبس نفسه ليس بروتوكول. كما ذكر أعلاه ، فإنه يوفر فقط واجهة لبرمجة TCP أو UDP.
ثانياً ، تجربته
حسنًا ، لدينا المفهوم ، دعنا نأخذ مثالًا:
1. إنشاء server.js
نسخة الكود كما يلي:
var net = require ('net') ؛
var server = net.createserver (function (c) {// connection beasherer
console.log ("خادم متصل") ؛
c.on ("end" ، function () {
console.log ("تم فصل الخادم") ؛
}) ؛
C.Write ("Hello ، BigBear!/R/N") ؛
C.Pipe (C) ؛
}) ؛
server.listen (8124 ، function () {// الاستماع المستمع
console.log ("Server Bound") ؛
}) ؛
2. إنشاء client.js
نسخة الكود كما يلي:
var net = require ('net') ؛
var client = net.connect ({
الميناء: 8124
} ، function () {// connect leader
console.log ("Client Connected") ؛
client.write ('Hello ، baby!/r/n') ؛
}) ؛
client.on ("البيانات" ، الدالة (البيانات) {
console.log (data.toString ()) ؛
client.end () ؛
}) ؛
client.on ("end" ، function () {
console.log ("Disconnect Client") ؛
}) ؛
دعونا نحلل:
Server ------ net.createServer ينشئ خدمة TCP. هذه الخدمة ملزمة (server.listen) على المنفذ 8124. بعد إنشاء الخادم ، نرى وظيفة رد الاتصال.
عند استدعاء الوظيفة أعلاه ، تكون المعلمة أيضًا وظيفة ، وتقبل المقبس ، وأنبوب تم إنشاؤه بواسطة طرق أخرى ، ووظائفها مخصصة للتفاعل بين البيانات.
يحتاج العميل إلى استقبال الأنبوب. إذا لم يكن هناك وصول عميل إلى الخادم في هذه اللحظة ، فلن يكون هذا المقبس موجودًا.
كما يوحي الاسم ، يتم توصيل客户端------net.connect بالخادم. المعلمة الأولى هي كائن. يتم تعيين المنفذ (المنفذ) على 8124 ، وهو المنفذ الذي يستمع إليه الخادم الخاص بنا. نظرًا لأن المعلمة المضيفة لم يتم تعيينها ، فإن الافتراضي هو مضيف محلي (محلي).
في الخادم ، يعد المقبس أحد طرفي خط الأنابيب ، وفي العميل ، العميل نفسه هو أحد طرفي خط الأنابيب. إذا تم توصيل العديد من العملاء بالخادم ، فسيقوم الخادم بإنشاء مآخذ متعددة ، ويتوافق كل مقبس مع عميل.
نتائج التشغيل:
3. مقدمة الحالة
(1) الرمز التالي هو مجرد إخراج الخادم قطعة من النص إلى العميل لإكمال الاتصال في اتجاه واحد من الخادم إلى العميل.
نسخة الكود كما يلي:
// sever-> اتصال عميل في اتجاه واحد
var net = require ('net') ؛
var chatserver = net.createserver () ؛
chatserver.on ('connection' ، function (client) {
client.write ('hi!/n') ؛ // يقوم الخادم بإخراج المعلومات إلى العميل ويستخدم طريقة الكتابة ()
client.write ('bye!/n') ؛
client.end () ؛ // ينهي الخادم الجلسة
}) ؛
chatserver.listen (9000) ؛
اختبار Telnet: Telnet127.0.0.1: 9000
بعد تنفيذ Telnet ، اتصل بنقطة الخدمة ، وتعليقات على شخصيات HI! وداعا! ، وإنهاء برنامج الخادم على الفور وإنهاء الاتصال.
ماذا لو أردنا أن يتصل الخادم بالمعلومات بالعميل؟
يمكنك الاستماع إلى حدث server.data وعدم إحباط الاتصال (أو أنه سينهي الرسائل على الفور من العميل الذي لا يمكن قبوله).
(2) ، استمع إلى حدث server.data ولا تقم بإحباط الاتصال (وإلا ، لن تتمكن الرسائل من العميل من قبولها على الفور).
نسخة الكود كما يلي:
// استنادًا إلى السابق ، تنفيذ العميل-> الاتصالات ، وهو اتصال ثنائي الاتجاه
var net = require ('net') ؛
var chatserver = net.createserver () ،
ClientList = [] ؛
chatserver.on ('connection' ، function (client) {
// يمكن لـ JS إضافة خصائص بحرية إلى الكائنات. نضيف هنا سمة مخصصة للاسم للإشارة إلى العميل (عنوان + منفذ العميل يعتمد عليه)
client.name = client.remoteaddress + ':' + client.Remoteport ؛
client.write ('hi' + client.name + '!/n') ؛
ClientList.push (Client) ؛
client.on ('data' ، function (data) {
البث (البيانات ، العميل) ؛ // قبول المعلومات من العميل
}) ؛
}) ؛
دالة البث (الرسالة ، العميل) {
لـ (var i = 0 ؛ i <clientlist.length ؛ i+= 1) {
إذا (العميل! == clientlist [i]) {
ClientList [i] .write (client.name + "يقول" + رسالة) ؛
}
}
}
chatserver.listen (9000) ؛
هل المذكورة أعلاه رمز كامل؟ قلنا أن هناك مشكلة أخرى لم يتم أخذها في الاعتبار: أي بمجرد خروج العميل ، يبقى في قائمة العميل ، والتي من الواضح أنها مؤشر فارغ.
(3) معالجة العميل
نسخة الكود كما يلي:
chatserver.on ('connection' ، function (client) {
client.name = client.remoteaddress + ':' + client.Remoteport
client.write ('hi' + client.name + '!/n') ؛
clientlist.push (عميل)
client.on ('data' ، function (data) {
البث (البيانات ، العميل)
})
client.on ('end' ، function () {
clientlist.splice (clientlist.indexof (client) ، 1) ؛ // حذف عنصر الصيغة في الصفيف.
})
})
لقد زودنا NodetCpapi بحدث نهائي ، أي عندما يقوم العميل بإحباط الاتصال بالخادم.
(4) تحسين البث
نسخة الكود كما يلي:
دالة البث (الرسالة ، العميل) {
var cleanup = []
لـ (var i = 0 ؛ i <clientlist.length ؛ i+= 1) {
إذا (العميل! == clientlist [i]) {
if (clientlist [i] .ritable) {// تحقق مما إذا كانت المقابس قابلة للكتابة أولاً
ClientList [i] .write (client.name + "يقول" + رسالة)
} آخر {
cleanup.push (clientlist [i]) // إذا لم يكن قابلاً للكتابة ، فقم بجمعه وتدميره. قبل التدمير ، يجب تدمير Socket.destroy () بواسطة API.
ClientList [i] .destroy ()
}
}
} // إزالة العقد الميتة من حلقة الكتابة لتجنب فهرس حلقة القمامة
لـ (i = 0 ؛ i <cleanup.length ؛ i+= 1) {
clientlist.splice (clientlist.indexof (cleanup [i]) ، 1)
}
}
لاحظ أنه بمجرد عدم تشغيل "النهاية" ، سيحدث استثناء ، وبالتالي سيتم إجراء أعمال التحسين.
(5) يوفر Netapi أيضًا حدث خطأ لالتقاط استثناءات العميل
نسخة الكود كما يلي:
client.on ('error' ، function (e) {
console.log (e) ؛
}) ؛
أربعة ، دعونا نلخص
1. فهم المفاهيم ذات الصلة للبداية
2. فهم العلاقة بين HTTP والوحدات النمطية
3. بناءً على الأمثلة في هذه المقالة ، يرجى الرجوع إلى واجهات برمجة التطبيقات ذات الصلة لممارسة.
4. أفكار الاتصال بين عميل المقبس والخادم
5. إذا كنت مهتمًا ، فيمكنك تحسين مثال غرفة الدردشة تلك