SSD Nodes Learn 🎉 VPS من $5.50/شهر
الأدلة Matt Connorبقلم Matt Connor

استضافة مؤتمرات الفيديو ذاتياً على VPS: احسب السعة أولاً

اكتشف كيف تحدد معادلة عرض النطاق حجم VPS، وقارن Jitsi وBigBlueButton وGalène من حيث RAM ومنافذ UDP ومشكلات NAT.

استضافة مؤتمرات الفيديو ذاتياً على VPS مشكلة تتعلق بعرض النطاق الترددي

تفشل مؤتمرات الفيديو المستضافة ذاتياً على الخوادم الصغيرة لسبب واحد، ونادراً ما يكون السبب هو التثبيت. مكوّن الخادم الذي تستخدمه كل أداة حديثة هو SFU (وحدة إعادة التوجيه الانتقائي). يستقبل تدفق فيديو واحداً من كل مشارك، ثم يوجّه نسخة منه إلى كل مشارك آخر. لذلك تزداد حركة الشبكة الخارجة من الخادم تربيعياً مع زيادة عدد المشاركين. سيشغّل VPS بسعة 1 GB أو 2 GB على وصلة مشتركة البرنامج بشكل طبيعي. لكنه لن يتحمل اجتماع all-hands الذي تتصوره.

لذلك نفّذ العمل بهذا الترتيب. أحصِ عدد المشاركين، واحسب معدل النقل بالميغابت، ثم اختر الخادم. يستغرق التثبيت عشرين دقيقة من النسخ واللصق. أما سعة الوصلة الصاعدة فهي التي تحدد ما إذا كان سيتمكن أي شخص من سماعك.

لماذا يزداد عرض النطاق الترددي مع مربع عدد المشاركين؟

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

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

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

والآن لنحسب استهلاك SFU. لنفترض أن كل شخص يرسل فيديو بسرعة 1.2 Mbps، وأن لا أحد أوقف الكاميرا. يستقبل الخادم N مضروباً في 1.2 Mbps، وهذا نمو خطي وغير مقلق. ويرسل الخادم N مضروباً في (N ناقص 1) مضروباً في 1.2 Mbps، لأن كل واحد من الأشخاص N يجب أن يستقبل الدفقات N ناقص 1 الخاصة بالمشاركين الآخرين. هذا هو الرقم الثاني الذي ينهي المشاريع.

ChartSFU outbound traffic, arithmetic model at 1.2 Mbps per sender
The data behind this chart
[
  {
    "label": "4 people",
    "sfu_egress_mbps": 14.4,
    "egress_gb_per_hour": 6.5,
    "monthly_volume_tb": 0.13
  },
  {
    "label": "8 people",
    "sfu_egress_mbps": 67.2,
    "egress_gb_per_hour": 30.2,
    "monthly_volume_tb": 0.6
  },
  {
    "label": "15 people",
    "sfu_egress_mbps": 252,
    "egress_gb_per_hour": 113.4,
    "monthly_volume_tb": 2.3
  },
  {
    "label": "30 people",
    "sfu_egress_mbps": "1,044",
    "egress_gb_per_hour": 469.8,
    "monthly_volume_tb": 9.4
  },
  {
    "label": "50 people",
    "sfu_egress_mbps": "2,940",
    "egress_gb_per_hour": "1,323",
    "monthly_volume_tb": 26.5
  }
]

هذه الصفوف حسابات رياضية، وليست قياساً لخادم محدد. يفترض العمود الشهري إجراء مكالمات لمدة عشرين ساعة في الشهر. اقرأ الصف الأخير أولاً. يحتاج خمسون شخصاً مع تشغيل الكاميرات إلى 2,940 Mbps من حركة البيانات الصادرة المستمرة من جهاز واحد. ويحتاج ثلاثون شخصاً إلى 1,044 Mbps. أما أربعة أشخاص فيحتاجون إلى 14.4 Mbps، وهو معدل يمكن لأي VPS التعامل معه من دون ملاحظة تُذكر. بين صف الأربعة أشخاص وصف الثلاثين شخصاً، يزداد عدد الأشخاص سبع مرات ونصف، بينما تزداد حركة البيانات الصادرة أكثر من سبعين مرة.

تأتي عمليات النشر الفعلية بأرقام أقل من هذه، ومن المفيد معرفة السبب بدقة. يستخدم كل من Jitsi وLiveKit تقنية simulcast: ينشر المرسل عدة طبقات للجودة في الوقت نفسه، ويمرر SFU طبقة منخفضة إلى أي شخص ليس ظاهراً على الشاشة. يوفّر Jitsi أيضاً إعداد last-N، الذي يمرر الفيديو لأحدث المتحدثين فقط. يوفر كلا الأسلوبين قدراً كبيراً من حركة البيانات. لكن لا يغيّر أي منهما شكل المنحنى، ويتوقف كلاهما عن المساعدة بمجرد أن يشغّل الجميع كاميراتهم ويثبتوا فيديو بعضهم بعضاً.

تذكر صفحة الخطة «منفذاً بسرعة 1 Gbps». هذه سرعة بطاقة الشبكة الافتراضية، وليست ضماناً لسرعة القفزة التالية في الشبكة. يكون الرابط مشتركاً مع المستأجرين الآخرين على المضيف الفعلي نفسه، لذلك تكون سرعة النقل المستمرة خلال ساعة مزدحمة أقل من سرعة المنفذ، وتُعد مكالمة جماعية حملاً مستمراً تحديداً. تتضمن معظم الخطط أيضاً حداً شهرياً لنقل البيانات، وبعد تجاوزه تُخفَّض السرعة أو تُفرض رسوم إضافية.

يظهر ذلك الحد في الفاتورة. تنقل عشرون ساعة من المكالمة التي تضم ثلاثين شخصاً خلال شهر واحد 9.4 TB خارج الخادم، بمعدل 469.8 GB في الساعة. وتنقل عشرون ساعة من المكالمة التي تضم خمسين شخصاً 26.5 TB. تحقّق من حد نقل البيانات قبل التحقق من مقدار RAM، وإذا كانت صفحة الخطة غامضة بشأنه، فهذه الغموض يقدّم لك الإجابة. إن قراءة عرض VPS منخفض التكلفة بطريقة صحيحة أهم لهذا الحمل من أهميتها لأي حمل آخر تقريباً.

Jitsi Meet: الخيار الافتراضي وما يحتاج إليه

يُعد Jitsi Meet الخيار الذي ينبغي لمعظم المستخدمين البدء به. يُثبَّت من مستودع Debian الخاص بالمشروع، ويضبط nginx وشهادة أثناء التثبيت، ويستخدم videobridge (JVB) منفذ UDP واحداً، مما يبقي قواعد الجدار الناري قصيرة. ويحتاج إلى Debian 11 أو أحدث، أو Ubuntu 22.04 أو أحدث.

sudo apt update
sudo apt install -y apt-transport-https curl gnupg
sudo add-apt-repository universe
sudo apt update
sudo curl -sL https://prosody.im/files/prosody-debian-packages.key -o /usr/share/keyrings/prosody-debian-packages.key
echo "deb [signed-by=/usr/share/keyrings/prosody-debian-packages.key] http://packages.prosody.im/debian $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/prosody-debian-packages.list
sudo apt install -y lua5.2
curl -sL https://download.jitsi.org/jitsi-key.gpg.key | sudo sh -c 'gpg --dearmor > /usr/share/keyrings/jitsi-keyring.gpg'
echo "deb [signed-by=/usr/share/keyrings/jitsi-keyring.gpg] https://download.jitsi.org stable/" | sudo tee /etc/apt/sources.list.d/jitsi-stable.list
sudo apt update
sudo apt install -y jitsi-meet

يسألك برنامج التثبيت عن اسم مضيف، ثم يعرض خيارات الشهادة. اختر خيار Let's Encrypt، وأدخل اسم نطاق يشير بالفعل إلى العنوان العام لهذا الخادم. تُصدر الشهادة عبر اختبار HTTP، لذلك يفشل هذا الإجراء إذا كان الاسم يشير إلى أي مكان آخر.

بعد ذلك، افتح المنافذ. هذه هي المنافذ التي يوثّقها الدليل، مع وضع SSH أولاً حتى لا يمنعك ufw enable من الوصول إلى الخادم:

sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 10000/udp
sudo ufw allow 3478/udp
sudo ufw allow 5349/tcp
sudo ufw enable

يخدم TCP 80 و443 تطبيق الويب، ويسمحان بتجديد الشهادة. ينقل UDP 10000 كل الصوت والفيديو، وهو المنفذ الذي ينساه المستخدمون غالباً. يرتبط UDP 3478 وTCP 5349 بخادم coturn الذي تثبّته حزمة Jitsi إلى جانب الجسر، وهو مسار بديل للمستخدمين الذين تحظر شبكاتهم UDP.

sudo systemctl status jitsi-videobridge2
sudo ss -ulnp | grep 10000

ينبغي أن يعرض الأمر الأول الخدمة على أنها نشطة. وينبغي أن يُظهر الأمر الثاني أن الجسر يستمع على UDP 10000. إذا لم يطبع شيئاً، فهذا يعني أن الجسر لم يبدأ، وسيبيّن /var/log/jitsi/jvb.log السبب.

لتحديد الموارد، ينشر دليل Jitsi نقطة بداية خاصة به، بينما ينشر BigBlueButton نقطة بداية أكبر بكثير:

ChartSizing each project publishes for one production server
The data behind this chart
[
  {
    "label": "Jitsi Meet",
    "ram_gb": 8,
    "cpu_cores": 4,
    "uplink_mbps": "1,000"
  },
  {
    "label": "BigBlueButton 3.0",
    "ram_gb": 16,
    "cpu_cores": 8,
    "uplink_mbps": 250
  }
]

يقترح دليل Jitsi استخدام 8 GB من ذاكرة RAM و4 أنوية مخصصة لخادم جاد، مع أن 1,000 Mbps من سعة الشبكة الصاعدة تكون كافية غالباً. ويذكر الدليل أن الإعدادات الأصغر يمكن أن تعمل بذاكرة 4 GB أو 2 GB. وهناك تفصيل مهم في تلك الصفحة: يمكن لـ Prosody، وهو خادم XMPP الذي يتولى الإشارات، استخدام نواة واحدة فقط. تفيد الأنوية الإضافية الجسر، ولا تفيد الإشارات.

لماذا ينضم الجميع إلى المكالمة، لكن لا يرى أحد الفيديو؟

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

عرّف الـbridge بالعنوانين. أضف mapping ثابتاً إلى /etc/jitsi/videobridge/jvb.conf:

ice4j {
  harvest {
    mapping {
      static-mappings = [
        {
          local-address = "10.0.0.5"
          public-address = "203.0.113.10"
        }
      ]
    }
  }
}

أعد التشغيل باستخدام sudo systemctl restart jitsi-videobridge2. خذ العنوان المحلي من ip -4 addr show، والعنوان العام من لوحة تحكم المزوّد. كانت الأدلة الأقدم تضبط القيمة نفسها في /etc/jitsi/videobridge/sip-communicator.properties باستخدام المفتاحين org.ice4j.ice.harvest.NAT_HARVESTER_LOCAL_ADDRESS وorg.ice4j.ice.harvest.NAT_HARVESTER_PUBLIC_ADDRESS. لا يزال ذلك يعمل، لكن يجب أن تستخدم عمليات التثبيت الجديدة كتلة mapping الموضحة أعلاه.

السبب الآخر هو جدار ناري لم تضبطه. يشغّل معظم المزوّدين جداراً نارياً للشبكة في لوحة التحكم، وهو منفصل عن ufw على الخادم، ويجب فتح UDP 10000 في كليهما. لمعرفة الطبقة التي تُسقط الحزم، شغّل sudo tcpdump -ni any udp port 10000 على الخادم أثناء انضمام شخص من خارج الشبكة. عدم وصول أي حزم يعني أن شيئاً ما لا يصل إلى الآلة، ولذلك يقع الحظر قبل نظام التشغيل. وصول الحزم مع بقاء مربعات الفيديو سوداء يعني أن الـbridge يجيب بعنوان لا يستطيع العميل الوصول إليه، وبالتالي تكون المشكلة في mapping. إذا لم تكن متأكداً من إعداد ufw نفسه، فراجع قواعد ufw التي يحتاج إليها VPS فعلياً لمعرفة ترتيب القواعد الذي يسبب المشكلات.

BigBlueButton: ثقيل ومقيّد بتصميمه ويحتاج إلى الخادم بالكامل

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

اعتباراً من أغسطس 2026، المسار المدعوم هو BigBlueButton 3.0 على Ubuntu 22.04، مع تحديده باستخدام علامة الإصدار jammy-300. متطلبات التشغيل الإنتاجية المعلنة للمشروع هي 16 GB من الذاكرة مع تفعيل swap، و8 نوى CPU ذات أداء مرتفع في التنفيذ بخيط واحد، وعرض نطاق متماثل قدره 250 Mbps، و500 GB من مساحة القرص إذا احتفظت بالتسجيلات، أو 50 GB إذا عطّلتها. المنافذ المطلوبة هي TCP 80 و443، بالإضافة إلى نطاق UDP من 16384 إلى 32768.

wget -q https://raw.githubusercontent.com/bigbluebutton/bbb-install/v3.0.x-release/bbb-install.sh
less bbb-install.sh
bash bbb-install.sh -w -v jammy-300 -s bbb.example.com -e info@example.com -g

توجّه أمثلة المشروع الخاصة بالسكربت مخرجاته مباشرة إلى bash. نزّل السكربت واقرأه أولاً، لأنه يعيد كتابة إعدادات nginx، ويثبّت مكدس الوسائط والصوت الخاص به، ويثبّت إصدارات الحزم، ويستولي على اسم المضيف. هذا جزء من التصميم وليس عيباً: يتوقع BigBlueButton أن يملك الخادم بالكامل. تضبط العلامة -w جدار الحماية، وتحدد -s اسم المضيف، بينما تمثل -e العنوان الذي يسجله Let's Encrypt، وتضيف -g واجهة Greenlight الأمامية. إذا كان الخادم نفسه ينهي TLS لخدمات أخرى، فانقل BigBlueButton إلى مكان آخر أو تأكد من فهمك لما يفعله إعداد nginx reverse proxy قبل أن يعدّله السكربت.

قارن الصفين في ذلك المخطط بعناية. يطلب BigBlueButton ضعف الذاكرة وضعف عدد النوى مقارنة باقتراح Jitsi، مع طلب ربع عرض النطاق فقط. لم تُقَس الرقمان بالطريقة نفسها، كما أنهما يفترضان أحجام غرف مختلفة؛ لذلك تعامل مع كل رقم باعتباره نقطة بداية لمشروعه، لا باعتباره مقارنة مباشرة بين مشروعين متماثلين. الفارق في CPU حقيقي، وينتج عن كل ما ينفذه BigBlueButton بالإضافة إلى تمرير الفيديو.

Galène: الخيار الخفيف

Galène هو SFU صغير مكتوب بلغة Go. يُبنى في صورة ملف ثنائي ثابت واحد، ويأتي مع عميل الويب الخاص به، ويتضمن خادم TURN، لذلك لا تحتاج إلى خادم XMPP أو بيئة تشغيل Java أو تطبيق Rails يجب إبقاؤه قيد التشغيل. إذا كان المطلوب مكالمة موثوقة لعشرة أشخاص على خادم متواضع، فجرّبه قبل أن تستنتج أنك تحتاج إلى عتاد أقوى.

sudo apt update && sudo apt install -y git golang-go
git clone https://github.com/jech/galene
cd galene
CGO_ENABLED=0 go build -ldflags='-s -w'
mkdir groups

حزمة golang-go في Ubuntu 24.04 هي Go 1.22. إذا أبلغ go build بأن الوحدة تحتاج إلى إصدار أحدث من Go، فثبّت toolchain حديثاً من go.dev بدلاً من محاولة معالجة مشكلة حزمة التوزيعة.

تستخدم Galène كلمة group للدلالة على الغرفة، وgroup هو ملف JSON:

echo '{"users": {"vimes": {"password":"sybil", "permissions":"op"}}}' > groups/night-watch.json
./galene &

افتح https://your.server:8443/group/night-watch/ وسجّل الدخول باستخدام vimes. تأتي بيانات الاعتماد هذه مباشرة من README الخاص بالمشروع، لذلك غيّرها قبل أن يصبح المنفذ متاحاً من أي مكان آخر. يوضّح المشروع وحدة systemd للنشر الفعلي:

[Unit]
Description=Galene
After=network.target

[Service]
Type=simple
WorkingDirectory=/home/galene
User=galene
Group=galene
ExecStart=/home/galene/galene
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

المنافذ هي TCP 8443 لواجهة الويب، وTCP وUDP 1194 لخادم TURN المضمّن، ونطاق من منافذ UDP العالية للوسائط. ثبّت هذا النطاق حتى تتمكن من كتابة قاعدة جدار ناري واحدة له:

./galene -udp-range 40000-40100

الخيار -turn هو المهم على VPS. يستمع -turn ':1194' على جميع عناوين IPv4 العامة. يعرّف -turn '203.0.113.1:1194' إلى Galène العنوان الذي سيراه العملاء فعلياً، وهذا ما تحتاج إليه عندما يكون عنوان الجهاز نفسه خاصاً. يعطّل -turn '' الخادم المضمّن، حتى تتمكن من توجيه الاتصالات إلى خادم خارجي عبر data/ice-servers.json. القيمة الافتراضية هي auto، التي تعمل مثل :1194 عند عدم وجود ice-servers.json.

يمكنك وضع nginx أمام واجهة الويب عبر ضبط proxyURL في data/config.json، ثم تمرير موقع /ws مع رؤوس ترقية WebSocket. انتبه إلى نطاق ذلك: ما زال العملاء ينشئون تدفقات UDP مباشرة واتصالات TCP مباشرة إلى منفذ TURN، لذلك يتولى reverse proxy الصفحة وإشارات الاتصال فقط. لا تمر الوسائط من خلاله.

تذكر وثائق Galène أنه يحتاج إلى موارد خادم محدودة جداً، ولا تنشر رقماً محدداً، لذلك لا تتوقع رقماً. تظل حسابات bandwidth المذكورة أعلاه منطبقة بالكامل. ما توفره هو الذاكرة والعناصر المتحركة لكل ما ليس جزءاً من SFU.

Owncast: من شخص واحد إلى عدد كبير، مع بقاء عرض النطاق خطياً

تكون متطلبات «مؤتمرات الفيديو» في كثير من الحالات عبارة عن شخص واحد يقدّم عرضاً لجمهور يكتب في الدردشة. إذا كان هذا هو الاستخدام لديك، فإن SFU ليست الأداة المناسبة، وتختلف التكلفة جذرياً. يستقبل Owncast دفق RTMP من OBS أو من برنامج ترميز مشابه، ويقدّم HLS عبر HTTPS العادي. يكون عرض النطاق لكل مشاهد خطياً بدلاً من أن يكون تربيعياً، ولأن المخرجات عبارة عن مقاطع HTTP عادية، يمكنك نقلها إلى تخزين كائني أو CDN والتوقف عن دفع تكلفتها على الخادم الأصلي.

curl -sL https://owncast.online/install.sh -o install-owncast.sh
less install-owncast.sh
bash install-owncast.sh

توضح وثائق المشروع أنه لا ينبغي تشغيله بحساب root، وأن عليك فحص أي script بعيد قبل تنفيذه. لذلك جرى تنفيذ التنزيل في خطوة منفصلة أعلاه. يجلب المثبّت الإصدار الحالي وملفاً ثنائياً لـ ffmpeg إذا لم يكن متوفراً لديك مسبقاً. شغّل ./owncast من دليل التثبيت، وافتح لوحة الإدارة على /admin عبر المنفذ 8080. اسم الدخول الافتراضي هو المستخدم admin، وكلمة المرور هي مفتاح الدفق الافتراضي abc123. غيّره قبل توجيه نطاق إلى الخادم.

تنتج عن تصميم HLS نتيجتان. يتأخر المشاهدون عن البث المباشر بضع ثوانٍ أو دقائق، لأن HLS يرسل مقاطع كاملة، ولذلك لا تصلح المحادثة التفاعلية ذهاباً وإياباً. كذلك لا يوجد UDP ولا TURN في أي نقطة من المسار، ولذلك يمكنه الوصول إلى شبكات يتعذر فيها اتصال WebRTC تماماً.

Owncast هو أيضاً الأداة الوحيدة هنا التي تجري transcoding عن قصد. كل جودة إخراج تفعّلها تعني عملية ترميز أخرى باستخدام ffmpeg للدفق الوارد، وتستمر طوال مدة البث. على VPS صغير، وفّر جودة واحدة أو جودتين. أما خمس جودات فستستنزف CPU بينما تبقى الشبكة خاملة.

تشغيل Element Call على خادم Matrix تديره مسبقاً

إذا كنت تدير Matrix مسبقاً، فإن إضافة مكالمات الفيديو تكون إضافة إلى النظام بدلاً من تشغيل منتج ثانٍ. لكنها لا تزال تتطلب أكثر من حزمة واحدة. يحتاج Element Call إلى مكوّنين خلف خادم homeserver لديك. الأول هو LiveKit SFU، الذي يتولى إعادة توجيه الوسائط. والثاني هو خدمة تفويض MatrixRTC، element-hq/lk-jwt-service، التي تزوّد العميل بعنوان LiveKit WebSocket الموحّد ورمز JWT موقّع (JSON web token) للاتصال به. تستخدم هذه الخدمة واجهة Matrix federation API، لذلك تحتاج إلى Reverse Proxy ينهي TLS أمامها، وإلى اسم يمكن لـ federation الوصول إليه.

المنافذ الموثقة لـ LiveKit:

  • TCP 7880 لواجهة API وWebSocket الخاص بالعميل، خلف Proxy ينهي TLS
  • TCP 7881 لـ ICE عبر TCP، ويُستخدم عندما يتعذر على العميل الخروج عبر UDP
  • UDP 50000 إلى 60000 للوسائط، حيث يستخدم كل مشارك في الغرفة منفذين
  • UDP 3478 وTCP 5349 إذا فعّلت خادم TURN المضمّن، ويجب نقل 5349 إلى 443 ما لم يوجد load balancer أمامه

قد يبدو تخصيص منفذين لكل مشارك مقلقاً، لكنه ليس كذلك. يغطي نطاق من 10,000 منفذ آلاف المشاركين، وسينفد اتصال الرفع لديك قبل نفاد النطاق بوقت طويل. افتح النطاق كاملاً على أي حال، لأن فتح جزء منه يؤدي إلى فشل الاتصال لدى بعض المستخدمين ونجاحه لدى آخرين، وهذا أصعب أنواع الأعطال في التصحيح. أما إعداد جانب homeserver، فهو مهمة مستقلة ومشروح في تشغيل خادم Synapse homeserver على VPS.

لماذا يتعذر على شخص واحد الاتصال دائماً؟ TURN والشبكات التي تحظر UDP

أولاً، بعض المصطلحات، ويُستخدم كل منها مرة واحدة. ICE ‏(interactive connectivity establishment) هو العملية التي تستخدمها نقطتا نهاية WebRTC للعثور على مسار صالح بينهما. STUN ‏(session traversal utilities for NAT) هي خدمة صغيرة تخبر العميل كيف يبدو عنوانه العام من خارج الشبكة. TURN ‏(traversal using relays around NAT) هو مرحّل: عندما لا يتوفر مسار مباشر، يرسل الطرفان الوسائط إلى خادم TURN، ثم يعيد الخادم توجيهها.

تحتاج إلى TURN للمشاركين الموجودين على شبكات لا يمكنك رؤية تفاصيلها. قد يكون أحدهم على شبكة شركة أو حرم جامعي تحظر UDP الصادر بالكامل. وقد يكون آخر خلف NAT على مستوى مزود الخدمة يخصص منفذ مصدر مختلفاً لكل وجهة. يُسمى ذلك symmetric NAT، ويجعل العنوان الذي أبلغت عنه STUN عديم الفائدة.

العَرَض محدد. ينضم معظم الأشخاص ويعمل كل شيء. يرى شخص واحد قائمة المشاركين والمحادثة، لكنه يرى مربعاً أسود ومؤشراً دواراً. جمع المتصفح candidates، لكن لم يعمل أي زوج منها، وانتهت ICE بحالة فشل. في Chrome، يُظهر chrome://webrtc-internals المفتوح أثناء المحاولة أزواج candidates وحالة الفشل. اطلب من ذلك الشخص إعادة المحاولة من هاتف يستخدم بيانات الهاتف المحمول. إذا نجح الاتصال هناك، فالشبكة هي السبب، وTURN هو الحل.

يُعد TURN عبر TCP على المنفذين 443 أو 5349 حلاً احتياطياً يعمل في معظم الشبكات، لأن الشبكة التي تحظر TLS على 443 تكون قد حجبت الويب أيضاً. يثبت Jitsi حزمة coturn ويضبطها لك، ولهذا تتضمن قواعد الجدار الناري الموثقة لديه UDP 3478 وTCP 5349. يحتوي Galène على TURN مدمج في 1194. ويحتوي LiveKit على خادم TURN مضمّن يمكنك تفعيله في الإعدادات. إذا شغّلت coturn بنفسك:

sudo apt install -y coturn
sudo systemctl enable --now coturn
listening-port=3478
tls-listening-port=5349
fingerprint
use-auth-secret
static-auth-secret=REPLACE_WITH_A_LONG_RANDOM_STRING
realm=turn.example.com
cert=/etc/letsencrypt/live/turn.example.com/fullchain.pem
pkey=/etc/letsencrypt/live/turn.example.com/privkey.pem
min-port=49152
max-port=65535
no-multicast-peers

في Debian وUbuntu، لن تبدأ الخدمة الموفرة في الحزمة حتى تضبط TURNSERVER_ENABLED=1 في /etc/default/coturn. يبدو coturn المثبت ولكن غير المفعّل من الخارج مطابقاً تماماً لعدم وجود TURN، ولهذا يكلّف هذا السطر الواحد بعض الأشخاص أمسيات كاملة.

أما التكلفة التي لا يذكرها أحد. ينقل المرحّل الوسائط كاملة لكل مشارك مُرحّل في الاتجاهين. عندما يشارك coturn الجهاز مع SFU، يمر معظم ذلك traffic عبر loopback، وتكون الكلفة على CPU بدلاً من uplink، كما أن مستمع TLS يشفّر كل حزمة مرة ثانية فوق DTLS الذي تحمله الوسائط أصلاً. وعندما تنقل TURN إلى جهاز مستقل، يحتاج ذلك الجهاز إلى خطة bandwidth خاصة به، محسوبة بالطريقة نفسها المستخدمة لخطة SFU. كما يحوّل TURN عبر TCP وسائط الوقت الفعلي إلى stream موثوق، لذلك تُعاد حزمة مفقودة بدلاً من تجاوزها، ويتراكم التأخير لدى المشارك المُرحّل على وصلة كثيرة الفقد بدلاً من حدوث خلل قصير. المرحّل حل احتياطي يحقق الاتصال، لكن بجودة كان المسار المباشر سيتفوق عليها.

متى يرمّز SFU الوسائط، وما تكلفة ذلك؟

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

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

الاتصال الهاتفي هو الميزة الثانية. يعني ربط خط هاتفي بمؤتمر تحويل Opus عند 48 kHz إلى الصيغة التي تقبلها شبكة الهاتف، وعادةً G.711 عند 8 kHz، في الاتجاهين وبصورة مستمرة طوال المكالمة. ترميز الصوت أقل تكلفة بكثير من ترميز الفيديو، لكنه يعمل لكل مسار مكالمة ولا يتوقف، ولذلك تتناسب التكلفة مع عدد المتصلين. إذا أردت رقم اتصال هاتفي، فإن خادم VoIP مستضاف ذاتياً هو المكوّن الذي ينفذ هذه المهمة، ومن الأفضل تشغيله على خادم مستقل للسبب نفسه الذي ينطبق على Jibri.

ما الحجم الفعلي للخادم الذي تحتاج إليه؟

بالنسبة إلى شخصين، لا تحتاج إلى موارد تُذكر. يفعّل Jitsi وضع الند للند افتراضياً عندما يكون عدد المشاركين اثنين تماماً. في هذا الوضع، يتوقف المؤتمر عن إرسال البيانات عبر videobridge ويستخدم الاتصال المباشر بدلاً من ذلك. يؤدي انضمام شخص ثالث إلى إعادة التبديل إلى الـbridge. لذلك، يُعد VPS بسعة 1 GB يشغّل Jitsi مناسباً لمكالمة فردية بين شخصين، لكنه خيار ضعيف لأربعة أشخاص. ولهذا تتكرر عبارة «لقد نجح عندما اختبرته» كثيراً.

بالنسبة إلى ما يصل إلى عشرة أشخاص تقريباً مع تشغيل الكاميرات، يكون استهلاك الخروج البالغ 67.2 Mbps عند ثمانية مشاركين ضمن قدرة رفع VPS عادي. سيشغّل معالجان افتراضيان وذاكرة 4 GB ‏Jitsi أو Galène بهذا الحجم، ما دمت لا تسجّل المكالمة. راقب عداد نقل البيانات بدلاً من مخطط CPU.

بالنسبة إلى ثلاثين شخصاً، يبلغ أسوأ استهلاك مستمر 1,044 Mbps، ويعادل تشغيله لمدة عشرين ساعة 9.4 TB. عند هذا الحجم، احسب تكلفة النطاق الترددي قبل حساب تكلفة الخادم. فعّل last-N كي يمرر الـbridge المتحدثين الأخيرين فقط، واجعل إيقاف الكاميرا هو الإعداد الافتراضي للحاضرين، وضع SFU في موقع يوفّر حصة نقل بيانات تكفي بعد إجراء الحسابات.

بعد ذلك، لا يعود VPS واحد مناسباً لهذا التصميم. إما أن يكون الحدث بثاً فعلياً، وعندها تكون Owncast مع CDN أقل تكلفة بكثير، أو أنك تحتاج إلى أكثر من videobridge واحد خلف طبقة signalling واحدة. وهذا مشروع مختلف عن المشروع الذي بدأته.

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

FAQ

لماذا يستطيع الأشخاص الانضمام إلى اجتماع Jitsi، لكن لا يستطيعون رؤية بعضهم أو سماعهم؟

تنتقل المحادثة وقائمة المشاركين عبر قناة الإشارة، وهي تستخدم TCP على المنفذ 443، بينما يستخدم الصوت والفيديو UDP على المنفذ 10000 للوصول إلى videobridge. إذا امتلأت قائمة المشاركين وبقيت كل مربعات الفيديو سوداء، فهذا يعني أن مسار الوسائط معطّل بينما تعمل قناة الإشارة. تحقّق من السماح بـUDP 10000 في جدارَي الحماية: الجدار الموجود على الخادم، وجدار الحماية الشبكي المنفصل في لوحة تحكم المزوّد. ثم تحقّق من أن bridge يعرف عنوانه العام. على جهاز افتراضي يملك عنواناً خاصاً وعنواناً عاماً مربوطاً به، أضف تعييناً ثابتاً ضمن ice4j.harvest.mapping في /etc/jitsi/videobridge/jvb.conf، ثم أعد تشغيل jitsi-videobridge2. يخبرك تشغيل sudo tcpdump -ni any udp port 10000 أثناء انضمام أحد الأشخاص بأي المسارين توجد المشكلة، لأن عدم وصول أي حزم يعني أن الحظر يحدث قبل نظام التشغيل.

ما مقدار النطاق الترددي الذي تستخدمه مكالمة فيديو تضم 30 شخصاً؟

في أسوأ حالة، عندما يشغّل الجميع الكاميرات ويمرّر SFU طبقة كاملة الجودة إلى كل مشارك، يخرج من الخادم نحو 1,044 Mbps، أي 469.8 GB في الساعة. هذا ناتج حسابي لـN في (N ناقص 1) من التدفقات بسرعة 1.2 Mbps لكل تدفق، وليس قياساً لإعدادك. يقلل Simulcast وإعداد last-N هذا المقدار كثيراً في الاستخدام العادي، لأن معظم المشاركين لا يظهرون على الشاشة في الوقت نفسه. مع ذلك، صمّم السعة لتقترب من أسوأ حالة، لأن أسوأ حالة تحدث في الاجتماعات العامة عندما يشغّل الجميع كاميراتهم دفعة واحدة.

هل يمكنني تشغيل Jitsi Meet على VPS بسعة 1 GB؟

سيُثبَّت البرنامج، وستعمل مكالمة تضم شخصين، ويرجع ذلك جزئياً إلى أن Jitsi يستخدم وضع peer to peer عند وجود مشاركين اثنين تحديداً، ويتجاوز videobridge بالكامل. لكنه ليس خادماً مفيداً للمكالمات الجماعية. تحتاج Prosody وvideobridge وبيئة تشغيل Java إلى الذاكرة، وتقترح وثائق الدليل نفسها 8 GB لنشر جاد، كما أن حساب النطاق الترددي سيصبح عائقاً قبل الذاكرة. إذا كان خادم بسعة 1 GB هو المتاح لديك، فإن Galène أنسب لهذا الحجم من Jitsi.

هل ما زلت بحاجة إلى خادم TURN إذا كان لدى VPS عنوان IP عام؟

نعم. المشكلة التي يحلها TURN تقع في الطرف الآخر من المكالمة. لا يستطيع مشارك موجود على شبكة شركة تحظر UDP الصادر، أو خلف NAT من فئة مزوّدي الاتصالات يعيّن منفذ مصدر مختلفاً لكل وجهة، إنشاء مسار وسائط مباشر، مهما كان عنوان خادمك عاماً. يوفّر TURN عبر TCP على المنفذ 443 أو 5349 مرحّلاً يبدو لجدار الحماية مثل حركة مرور ويب عادية. يضبط تثبيت حزمة Jitsi coturn لهذا الغرض تلقائياً، ولذلك تفتح قواعد جدار الحماية الموثقة المنفذ UDP 3478 والمنفذ TCP 5349.

لماذا يحتاج BigBlueButton إلى عتاد أقوى بكثير من Jitsi Meet؟

لأنه ينفّذ وظائف أكثر بكثير من تمرير الفيديو. متطلبات التشغيل المنشورة له هي 16 GB من الذاكرة و8 نواة، مقارنةً بـ8 GB و4 نواة في دليل Jitsi. يشغّل BigBlueButton حزمة مؤتمرات صوتية كاملة، وطبقة للسبورة المشتركة والعروض التقديمية، وخط أنابيب للتسجيل والمعالجة اللاحقة، وواجهة ويب مع حسابات المستخدمين، وكل ذلك على الجهاز نفسه. كما أنه يفرض قيوداً محددة على المنصة: اعتباراً من August 2026، يكون التثبيت المدعوم هو الإصدار 3.0 على Ubuntu 22.04. تأتي مجموعتا الأرقام من وثائق المشروعين نفسيهما، وهما نقطتا بدء وليستا قياسات لحِمل العمل لديك.

#jitsi#webrtc#video-conferencing#استضافة ذاتية#bandwidth