SSD Nodes Learn Hosting plans →
الأدلة Matt Connorبقلم Matt Connor · آخر تحديث في 2026-09-28

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

احسب سعة الخادم قبل التثبيت: تعرّف إلى سبب نمو النقل تربيعياً، وقارن Jitsi وBigBlueButton وGalène في الذاكرة ومنافذ UDP ومشكلات NAT.

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

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

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

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

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

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

البنية الأقدم هي MCU (multipoint control unit). يفك ترميز كل تدفق وارد، ويدمج التدفقات في صورة واحدة، ثم يعيد ترميز تلك الصورة. يكون عرض النطاق الترددي الصادر ضئيلاً. لكن تكلفة 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 بجانب الـbridge، وهو مسار احتياطي لمن تحظر شبكاتهم UDP.

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

يجب أن يعرض الأمر الأول حالة الخدمة على أنها active. ويجب أن يعرض الأمر الثاني أن الـbridge يستمع على UDP 10000. إذا لم يعرض شيئاً، فهذا يعني أن الـbridge لم يبدأ، وسيبيّن /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 الذي يتولى الإشارات، استخدام نواة واحدة فقط. تساعد النوى الإضافية الـbridge، ولا تفيد الإشارات.

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

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

أخبر bridge بالعنوانين. أضف تعييناً ثابتاً إلى /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. لا يزال هذان الإعدادان يعملان، لكن يجب أن تستخدم عمليات التثبيت الجديدة كتلة التعيين أعلاه.

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

BigBlueButton: ثقيل ومتطلب، ويريد الخادم بأكمله

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

اعتباراً من August 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 أنه يحتاج إلى موارد خادم محدودة جداً، ولا تنشر رقماً محدداً، لذلك لا تتوقع رقماً. ما ورد أعلاه عن حساب عرض النطاق ينطبق بالكامل. ما توفره هو الذاكرة والمكوّنات المتحركة لكل ما لا يتعلق بـSFU.

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

تتعلق متطلبات كثيرة لما يُسمى «مؤتمرات الفيديو» في الواقع بشخص واحد يقدّم عرضاً لجمهور يكتب في الدردشة. إذا كان هذا هو سيناريو استخدامك، فإن SFU ليس الأداة المناسبة، وتختلف التكاليف جذرياً. يستقبل Owncast بثاً عبر RTMP من OBS أو من مُرمِّز مشابه، ويقدّم HLS عبر HTTPS عادي. يكون النطاق الترددي لكل مشاهد خطياً بدلاً من أن يكون تربيعياً، وبما أن الناتج عبارة عن مقاطع HTTP عادية، يمكنك نقله خلف object storage أو 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، التي تزوّد العميل بعنوان WebSocket الخاص بـLiveKit وJWT موقّع (JSON web token) للاتصال به. تستخدم هذه الخدمة Matrix federation API، ولذلك تحتاج إلى TLS reverse proxy أمامها وإلى اسم يمكن لخوادم 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 منفذ آلاف المشاركين، وسينفد uplink لديك قبل أن ينفد النطاق بوقت طويل. افتح النطاق بأكمله على أي حال، لأن فتح جزء من النطاق يفشل لدى بعض الأشخاص ويعمل لدى آخرين، وهذا أسوأ نوع من الأعطال من حيث صعوبة تصحيحه. أما إعداد ذلك على جانب homeserver فهو مهمة مستقلة، وقد غُطّيت في تشغيل Synapse homeserver على VPS.

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

إليك بعض المصطلحات أولاً، ويُستخدم كل منها مرة واحدة. ICE (إنشاء الاتصال التفاعلي) هو العملية التي يستخدمها طرفا WebRTC للعثور على مسار صالح بينهما. STUN (أدوات عبور الجلسات عبر NAT) هي خدمة صغيرة تُخبر العميل كيف يبدو عنوانه العام من خارج الشبكة. TURN (العبور باستخدام مرحلات حول NAT) هو مرحّل: عندما لا يوجد مسار مباشر، يرسل الطرفان الوسائط إلى خادم TURN، ثم يعيد توجيهها.

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

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

ضع هذه الإعدادات في /etc/turnserver.conf. في Debian وUbuntu، تبدأ الحزمة تشغيل coturn فور تثبيتها، باستخدام الإصدار الافتراضي من ذلك الملف، ولذلك يعثر عليه enable --now أعلاه قيد التشغيل مسبقاً ولا يغيّر شيئاً. تصبح إعداداتك فعالة عند تشغيل sudo systemctl restart coturn، وكل تعديل لاحق للملف يحتاج إلى إعادة التشغيل نفسها. ترشدك الأدلة الأقدم أيضاً إلى ضبط TURNSERVER_ENABLED=1 في /etc/default/coturn. لا يقرأ هذا الخيار إلا برنامج init القديم. أما وحدة systemd التي تشغّلها الحزم الحالية فلا تقرؤه، لذلك لا يغيّر ذلك السطر شيئاً، ويستمر coturn الذي لم تُعد تشغيله في استخدام الملف الافتراضي.

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

متى يجري 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 عادي على الإرسال المستمر. يمكن لوحدتي CPU افتراضيتين وذاكرة 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 runtime إلى الذاكرة، كما أن التوصية الواردة في الدليل نفسه هي 8 GB لنشر جاد، وسيتسبب حساب النطاق الترددي في المشكلة قبل الذاكرة. إذا كان لديك خادم بسعة 1 GB فقط، فإن Galène أنسب لهذا الحجم من Jitsi.

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

نعم. المشكلة التي يحلها TURN تكون في الطرف الآخر من المكالمة. لا يستطيع مشارك موجود على شبكة شركة تحظر UDP الصادر، أو خلف Carrier-Grade 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