تاریخچه ماتریکس، نکات و بهترین روش‌هایی که بهش رسیدم

هدف این نوشته هم‌رسانی یه سری اطلاعات و بهترین روش‌هاییه که بهشون رسیدم (Best Practices)

از اون‌جایی که یه تعدادی از بچه‌ها دارن سرورهای ماتریکس رو میزبانی می‌کنن یا می‌خوان بکنن، واسه همین گفتم یه سری تجربیاتی که به ذهنم می‌رسه یا نکاتی چیزی بود رو اینجا بگم. همه رو زیر همین پست می‌نویسم که یه جا جمع شه، پس هر چند وقتی ممکنه این پست به روز بشه.

تاریخچه

ماتریکس همون‌طور که احتمالا می‌دونید پروتکل این ماجراست و ایده‌اش بر می‌گرده به ۲۰۱۴ که کمپانی Amdocs که تو همین زمینه ارتباطات و تکنولوژی فعال بود می‌خواست ابزار چت خودشو درست کنه و شروع می‌کنن روش کار کردن و یه چند تا کنفرانس و فلانم میرن که یه کم ایده صدا می‌کنه، سال ۲۰۱۵ میان پروژه رو منتقل می‌کنن به یه شرکت خواهر و اسمشو میذارن Vector Creations Limited (تو مایه‌های کمپانی مسئولیت محدود خلاقیت‌های وکتور).

خلاصه یه مدت تو سر خودشون و پروژه می‌زنن و می‌بینن نه! هم پیچیده‌اس هم دردسرای سیاسی داره و حالا بیا به این دولت جواب پس بده به اون یکی بگو آقا پیاما رو نمی‌تونم بهت بدم و فلان. آخرش ۲۰۱۷ تصمیم می‌گیرن بودجه پروژه رو قطع کنن. اعضای اصلی تیم فنیم که کلشون خراب میشه میگن ای بابا یعنی چی؟ پس ما میریم خودمون روش کار می‌کنیم. میرن یه شرکت تو انگلیس می‌زنن به اسم “New Vector Limited” (همون شرکت مسئولیت محدود وکتور جدید!) اسم اپو هم میذارن Riot (یعنی شورش!). کلا اینا با نام‌گذاری به شدت درگیرن.

یه مدتم اینا تو سر و کله خودشون می‌زنن بعد می‌بینن نمیشه. بودجه می‌خوایم! میان یه سری Patreon و Liberapay و اینا میذارن همچین خیلی دندون‌گیر نمیشه. بعد شروع می‌کنن تبلیغات و یه پادکست ویدیویی درست می‌کنن و تصمیم می‌گیرن خودشون میزبانی سرورای ماتریکس رو به کمپانیا پیشنهاد بدن که ما براتون راه می‌ندازیم و نگهداری می‌کنیم و اینا تحت عنوان modular.im سعی می‌کنن یه سری درآمد کسب کنن. سریع‌تر بریم جلو دیگه خیلی اتفاق مهمی نمیافته تا سال ۲۰۱۸.

سال ۲۰۱۸ استارتاپ Status که کارش تو حوزه اتریوم بود و اون موقع هم که بازارش حسابی داغ بود، ۵ میلیون دلار رو اینا سرمایه‌گذاری می‌کنه. که دیگه اینا خیلی حال می‌کنن و آخرای سال ۲۰۱۸ هم واسه این که تمرکز بیشتری رو هر قسمت از پروژه باشه، ماتریکس رو به عنوان “بنیاد منافع اجتماعی ماتریکس” ثبت می‌کنن که هدفش فقط کار کردن روی خود پروتکله. من تقریبا همین جاها با پروژه آشنا میشم ولی هنوز استفاده جدی نمی‌کنم. Riot خیلی خسته بود همون اول کار باگ بود که میومد تو صورتت.

دیگه همین طوری کمپانیا و تیمای خفن شروع می‌کنن میان روی ماتریکس از KDE تا Mozilla و دولت‌های مختلف. کاربر که زیاد میشه یواش یواش مشکلات امنیتیش هم میاد بالا و یکی یکی درستش می‌کنن و همین وسطا هم سال ۲۰۱۹ از نسخه بتا خارج میشن و Synapse رو به عنوان پیاده‌سازی مرجع ماتریکس ارائه می‌کنن و ۸ و نیم میلیون دلار دیگه سرمایه جذب می‌کنن و دیگه همه چیز جدی‌تر میشه. منم که تازه ماتریکس رو نصب کرده بودم چند ماه بعدش دوباره با این تحولات مواجه شدم که شت دیگه ماتریکس فقط پروتکله و حالا باید synapse رو نصب کنم.

سال ۲۰۲۰ انقدر تو کامیونیتی بهشون گیر میدن که بابا این چه اسم مزخرفیه آخه؟ مثلا به رفیقم بگم اپ شورشو نصب کن؟! که دیگه خودشونم میان میگن آره آقا قبول داریم ریدیم، اسمشو عوض می‌کنن می‌ذارن المنت که الان در خدمتشون هستیم. در واقع این فقط یه تغییر نام نبود. کلا Synapse رو هم با خودشون می‌برن و کمپانی وکتور تبدیل میشه به Element HQ که اپش المنته و بکش Synapse و موازی با کمپانی Matrix کارشونو ادامه میدن. اون طرف پروتکل، این طرف اجرا.

دیگه خیلی اتفاق مهمی نمیافته تا سال ۲۰۲۴ که نسخه ۲ پروتکل ماتریکس ارائه میشه که تغییرات خیلی بزرگ و مهمی توش اتفاق میافته. برای همین به این فکر می‌کنن که خب اپ قبلیمون پایه‌اش همون Riot قدیمیه و برای گوشی اصلا چیز جالبی نیست، طراحیش قدیمی شده و خیلی کنده و کاربرپسند نیست. بیایم یه بار دیگه برای موبایل بنویسیمش ولی چون خیلی طول می‌کشه همه امکاناتو روش آماده کنیم و اون وقت نمی‌تونیم مثلا ۲ سال آپدیت ندیم همون اپ قبلی رو نگه می‌داریم تا یه مدت، اینو هم به اسم ElementX می‌بریم جلو.

برای درآمدزایی هم علاوه بر فاندی که می‌گیرن، شروع می‌کنن به نسخه دسکتاپ یه سری امکانات سازمانی و integration اضافه می‌کنن و از تو دلش یه اپ Element Pro هم در میارن که در کنار یه پنل خوشگل به عنوان یه پکیج می‌فروشنش به سازمانا و اینا.
پس دیگه ته ماجرای ماتریکس و سینپس و المنت و المنت اکس و المنت پرو رو درآوردیم.

بکند‌های ماتریکس

همون‌طور که گفتم سینپس پیاده‌سازی مرجعه و از بقیه کامل‌تره ولی و اما! بقیه هم هستن که میشه بهشون توجه کرد. لیست کاملشون اینجاس.

از پیاده‌سازی‌های دیگه سرور ماتریکس میشه به Dendrite اشاره کرد که بازم خودشون شروع کردن بنویسنش اما این دفعه با Go. که خیلی خوب پیش نرفت و توسعه‌اش متوقف شد و قرار شد رو همون Synapse متمرکز بشن و به جاش یه سری قسمتا رو با راست بزنن که مشکل پرفورمنس سینپس حل بشه که الان متد سینک جدیدشون (اسلایدینگ سینک) اگه اشتباه نکنم با راسته که هنوز آزمایشیه.

کامیونیتی هم یه سرور به اسم Conduit (چه قدر این اسمو هی می‌شنویم این روزا) با راست نوشت که صرفا در حد ارسال و دریافت پیام بود و امکانات خاصی نداشت اما از تو دلش یه خانواده به وجود اومد که فرزندش شد conduwuit و ۲ تا هم نوه داره به اسمای continuwuity و Tuwunel که این دو تا از نظر امکانات به سینپس نزدیک‌ترن ولی یه سری چیزا رو هنوز ندارن. در نقطه مقابل بسیار سبک‌تر و سریع‌ترن. continuwuity سعی کرده به سینپس نز‌دیک‌تر باشه و Tuwunel با تمرکز روی integration ها به سینپس پرو نزدیکه و سازمانی‌تره. نکته مهم اینه که بین اعضای خانواده Conduit می‌تونید مهاجرت کنید (بازم نه همشون به همشون) چون دیتابیساشون تا حدی با هم سازگاره. اما از سینپس و به سینپس نه و در نتیجه اگه قراره یه تعدادی کاربر داشته باشید که مهمونتون بشن، باید از اول انتخاب خودتونو بکنید.

اینجا لیست چیزایی که تو continuwuity پیاده کردن و نکردن رو می‌تونید ببینید:

https://forgejo.ellis.link/continuwuation/continuwuity/issues/880

پروپوزال‌ها

وقتی به عنوان میزبان تو مستندات چرخ می‌زنید MSCxxxx رو زیاد باهاش رو به رو میشید که اینا در واقع مثل پروپوزال‌ها یا ویژگی‌ها و امکانات تایید شده تو ماتریکس هستن (Matrix Specifications). اینجا می‌تونید در موردشون بیشتر بخونید:

https://spec.matrix.org/latest/

و اینم یه لیست کلی ازشون:

https://spec.matrix.org/proposals/#proposal-tracking

هر کدوم با یه عددی شناخته میشن و بعضی امکانات آزمایشی توی هوم‌سرورتون رو با این پیشوندها باید فعال کنید که در واقع یاد‌آور آزمایشی بودنشون هم هستن.

تجربه و بهترین روش‌ها (این قسمت به مرور به روز میشه)

بهینه‌سازی تماس‌های لایو‌کیت

اگه حال نداری همشو بخونی: اولویت لایوکیت رو برقراری ارتباط p2p با ICE/UDP ئه. تو بعضی شرایط به خصوص شرایطی مثل اینترنت ایران ارتباط RTC روی UDP یا خیلی کند و شکننده‌اس یا اصلا برقرار نمیشه، به خصوص رو اینترنت دیتای گوشی. چون خیلی از وی‌پی‌ان‌ها و پروکسی‌ها از این روش برای ارتباط استفاده می‌کنن برای همین مدام تو فشار می‌ذارنش. گزینه بعدی لایوکیت اینه که سوییچ کنه روی ICE/TCP که اونم در مواردی کند و شکننده میشه. ما می‌تونیم با فعال کردن TURN دست کم یه مرحله دیگه این بین قرار بدیم که به عنوان فال‌بک (جایگزین) اونو هم امتحان کنه.

برای جزئیات و مطالعات بیشتر ازتون دعوت می‌کنم یه نگاهی به مستندات لایو‌کیت (Livekit) بندازید تا با عملکردش و پروتکل‌های ارتباطیش بیشتر آشنا بشید. اینجا هم خیلی اطلاعات خوبی داده (به زبان ساده‌تر) که چرا این مدلی هندل کنن WebRTC رو تو بعضی شرایط بهتر کار می‌کنه:

https://bloggeek.me/webrtc-turn/

اینم از پیشنهاد کانفیگ خودش که البته ایراد داره :))

https://docs.livekit.io/transport/self-hosting/deployment/#domain-ssl-certificates-and-load-balancer

اینم توضیحات بهتر این که هر پارامتر تو کانفیگ لایوکیت چی کار می‌کنه:

https://github.com/livekit/livekit/blob/master/config-sample.yaml

حالا من این کارا رو برای فعال کردن TURN داخلی خود لایوکیت کردم (برای Coturn مجزا نباید این کارا رو بکنید و به جاش به لینک بالا قسمت turn_servers مراجعه کنید):

۱. برای حداقل کردن latency، شبکه لایوکیتو آورد رو هاست تو داکر کامپوزم:

livekit:
  image: livekit/livekit-server:latest
  command: --config /etc/livekit.yaml
  restart: always
  volumes:
    - ./synapse-data/livekit-config/livekit.yaml:/etc/livekit.yaml:ro
  network_mode: host

۲. مقادیر rmem_max و wmem_max رو یه مقدار بالاتر گذاشتم (اختیاری بر اساس تعداد کاربراتون):

sysctl -w net.core.rmem_max=2500000
sysctl -w net.core.wmem_max=2500000

البته اگه خواستید اضافه کنید بذاریدش تو /etc/sysctl.d/ که ماندگار بشه.

۳. تو لایوکیت ترن رو روشن کردم و به لایو‌کیت هم پورت‌های بیشتری دادم:

port: 7880
bind_addresses:
  - "0.0.0.0"
rtc:
  tcp_port: 7881
  port_range_start: 50000
  port_range_end: 51000
  use_external_ip: false
  node_ip: my_server_ip
room:
  auto_create: false
logging:
  level: info
turn:
  enabled: true
  domain: matrix.mysite.com
  tls_port: 5348
  # udp_port: 3478
  external_tls: true
  relay_range_start: 52000
  relay_range_end: 53000
keys:
  mykey: "key"

نکته ۱: domain رو باید چیزی ست کنید که بعدا می‌خواید تو nginx ریورس کنید رو TURN می‌تونه آدرس خود نمونه باشه یا هر زیردامنه دیگه. چون پورت مورد نظر ما 5349 ئه با آدرس خود نمونه به کانفلیکت نمی‌خوره. اما اگه لایوکیت رو دارید رو یه سرور مجزا راه‌اندازی می‌کنید که nginx یا سرویس دیگه‌ای پورت 443 رو اشغال نمی‌کنه، می‌تونید پورت رو بذارید رو 443 و مستقیم ترافیک رو بفرستید داخل TURN که طبیعتا کمی هم سریع‌تر میشه اما سرور مجزا می‌خواد. در این صورت شما باید خودتون cert رو بهش بدید تا SSL رو هندل کنه (به داکیومنت تنظیمات مراجعه کنید).

نکته ۲: باید رنج پورتای ترن رو هم مثل لایو‌کیت رو دیواره‌آتش ‌(Firewall) باز کنید - TURN/UDP برای من کار نکرد نمی‌دونم چرا کلا اتصالی برقرار نمیشد. اگه می‌خواید امتحانش کنید کافیه از کامنت بیارید بیرون و پورتشم رو فایروال باز کنید. اون node_ip ضروری نیست اما تو زمان نت داخلی، لایوکیت دیگه مجبور نیست از STUN گوگل درخواست بده برای آیپی چون دیفالتش اونه مگر این که سرور STUN خودتون رو داشته باشید یا TURN/UDP براتون کار کنه.

۴. ریورس پروکسی TURN/TLS رو هم این طوری تنظیم کردم:

# Turn configs - Element calls fallback when UDP doesn't work well
stream {
  upstream turn_tls {
    server 127.0.0.1:5348;
  }

  server {
    listen 5349 ssl;
    listen [::]:5349 ssl;

    proxy_pass turn_tls;
    proxy_timeout 3600s;

    ssl_preread on;
    ssl_certificate /etc/letsencrypt/live/matrix.mysite.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/matrix.mysite.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;
  }
}

این کانفیگ باید تو بلاک بیرونی باشه نه تو بلاک http. خودش بلاک stream ئه. اگه پترن sites-available/sites-enabled استفاده می‌کنید می‌تونید یه streams-available/streams-enabled هم درست کنید و تو nginx.conf اونو include کنید و فایل تنظیمتونو اونجا درست کنید. در غیر این صورت می‌تونید به انتهای nginx.conf اضافش کنید. پورت ۵۳۴۹ رو هم فراموش نشه باز کنید.

چیزی که تو تست‌هام متوجه شدم اینه که مهم‌ترین منبع برای تماس به خصوص تصویری CPUئه هر چی هسته بیشتر و هسته خلوت‌تری رو به تماس اختصاص بدید هم تاثیر بیشتری داره، هم تو تعداد و هم تو کم کردن تاخیر.