پرش به مطلب اصلی

KeepAliveServer

KeepAliveServer بخش سرور KeepAliveClient است. فریم‌های keepalive را که از کلاینت و در جهت upstream می‌رسند decode می‌کند، payloadهای عادی را به next می‌فرستد، به فریم ping با pong پاسخ می‌دهد و payloadهای downstream را در همان قالب فریم قرار می‌دهد.

این نود را فقط به‌عنوان peer متناظر KeepAliveClient به کار ببرید. ورودی upstream آن باید فریم‌شده باشد و به‌تنهایی بایت‌های معمولی و بدون فریم payload را تشخیص نمی‌دهد.

KeepAliveServer یک تونل عادی و قابل ترکیب است. Socket یا objectی از نوع line_t نمی‌سازد، line را آزاد نمی‌کند و timer دوره‌ای ندارد.

جایگاه رایج

جفت مستقیم داخل یک process:

TesterClient -> KeepAliveClient -> KeepAliveServer -> TesterServer

طرح‌بندی TCP دو-سرور:

client side: TcpListener -> KeepAliveClient -> TcpConnector
server side: TcpListener -> KeepAliveServer -> TcpConnector

هر تونل میان کلاینت و سرور باید بایت‌های فریم keepalive را بدون تغییر عبور دهد.

این نود چه می‌کند؟

  • با دریافت Init در upstream، state محلی line را مقداردهی اولیه می‌کند.
  • بایت‌های فریم‌شده upstream را تا کامل شدن فریم‌ها بافر می‌کند.
  • فریم‌های عادی upstream را decode و payload آن‌ها را به next می‌فرستد.
  • به ping frame‌های upstream با فرستادن downstream pong frame پاسخ می‌دهد.
  • pong frame‌های upstream را نادیده می‌گیرد.
  • فریم‌های عادی خالی و typeهای ناشناخته را دور می‌اندازد.
  • payloadهای downstream را به‌عنوان keepalive frame عادی encode می‌کند و به نود قبلی می‌فرستد.
  • payloadهای downstream بزرگ‌تر از 65534 بایت را به چند frame عادی تقسیم می‌کند.
  • state محلی line را از بین می‌برد و Finish را در همان جهت منتشر می‌کند.

سرور timer جداگانه‌ای برای keepalive ندارد؛ KeepAliveClient مسئول ساخت pingهای دوره‌ای است.

نمونه تنظیم

{
"name": "ka-server",
"type": "KeepAliveServer",
"settings": {},
"next": "service"
}

سمت کلاینت متناظر:

{
"name": "ka-client",
"type": "KeepAliveClient",
"settings": {
"ping-interval": 60000
},
"next": "transport"
}

فیلدهای اجباری

فیلدهای سطح اصلی:

فیلدنوعتوضیح
namestringنام یکتای نود در پیکربندی.
typestringباید دقیقاً "KeepAliveServer" باشد.
settingsobjectاختیاری. پیاده‌سازی فعلی تنظیم اختصاصی برای سرور ندارد.
nextstringدر استفاده عادی اجباری است. نود بعدی payloadهای decodeشده upstream را می‌گیرد.

KeepAliveServer باید نود قبلی داشته باشد و توسط KeepAliveClient متناظر قابل دسترس باشد.

تنظیمات

KeepAliveServer در حال حاضر تنظیم معنی‌داری ندارد. زمان‌بندی keepalive در KeepAliveClient با settings.ping-interval تنظیم می‌شود.

فرمت Frame

سرور از همان prefix سه‌بایتی client استفاده می‌کند:

Bytesفیلدتوضیح
0..1body lengthعدد صحیح unsigned و 16-bit با ترتیب big-endian. این طول شامل بایت type فریم به‌علاوه بایت‌های payload است.
2frame kind1 payload عادی، 2 ping، یا 3 pong.

نوع‌های frame:

KindمعنیBody payload
1payload عادیبایت‌های payload اصلی WaterWall.
2pingدر ترافیک keepalive عادی خالی است.
3pongپاسخ خالی به یک ping frame.

چون body length 16-bit است و kind byte را هم شامل می‌شود، حداکثر payload حمل‌شده توسط یک frame عادی 65534 بایت است. payloadهای downstream بزرگ‌تر به چند frame تقسیم می‌شوند.

رفتار جهت‌ها

Incoming callbackرفتار
upstream Initبافر خواندن را مقداردهی اولیه می‌کند و سپس Init را به next می‌فرستد.
upstream Payloadبایت‌ها را ورودی فریم‌شده KeepAliveClient در نظر می‌گیرد و payloadهای عادی decodeشده را به next می‌فرستد.
upstream Est / Pause / Resumeبه next فرستاده می‌شوند.
upstream Finishstate محلی را از بین می‌برد و سپس Finish را به next می‌فرستد.
downstream Payloadpayload را در یک یا چند فریم عادی encode و به نود قبلی ارسال می‌کند. بافر payloadهای خالی برای استفاده مجدد برمی‌گردد.
downstream Est / Pause / Resumeبه نود قبلی فرستاده می‌شوند.
downstream Finishstate محلی را از بین می‌برد و سپس Finish را به نود قبلی می‌فرستد.
downstream Initغیرفعال؛ رسیدن به این callback به‌عنوان chain flow نامعتبر fatal در نظر گرفته می‌شود.

پردازش ورودی Framed

بایت‌های upstream در یک buffer_stream_t جمع می‌شوند؛ بنابراین ممکن است یک فریم در چند callbackِ payload تکه‌تکه برسد یا چند فریم در یک callback دریافت شوند.

رفتار decoder محافظه‌کارانه است:

  • وقتی prefix یا body کامل نرسیده، منتظر بایت‌های بعدی می‌ماند.
  • اگر body length frame کمتر از 1 باشد، read stream پاک می‌شود
  • فریم‌های عادی خالی دور ریخته می‌شوند.
  • typeهای ناشناخته فریم دور ریخته می‌شوند.
  • اگر ورودی upstream buffer شده از 131074 بایت بیشتر شود، read stream پاک می‌شود

یادداشت‌های Buffer و Padding

KeepAliveServer هنگام encode کردن payloadهای downstream، prefix سه‌بایتی frame را prepend می‌کند، بنابراین متادیتای نود آن اعلام می‌کند:

required_padding_left = 3
layer_group = kNodeLayerAnything

اگر بافر فریم فضای کافی در سمت چپ برای prefix نداشته باشد، فریم حذف و بافر برای استفاده مجدد برگردانده می‌شود. در chain درست، محاسبه padding در WaterWall باید این فضا را رزرو کرده باشد.

وقتی line فعلی یک worker packet line باشد، سرور بررسی می‌کند که خروجی framed از kMaxAllowedPacketLength تجاوز نکند. اگر payload + 3 از این حد بگذرد، فریم کنار گذاشته می‌شود.

نکته‌های عملی

  • این نود را با KeepAliveClient جفت کنید؛ به‌تنهایی مفید نیست.
  • فریم‌های ping و pong داخلی جفت KeepAlive هستند و به‌عنوان payload به نودهای اطراف داده نمی‌شوند.
  • سرور به ping‌ها پاسخ می‌دهد، اما health سمت client را اندازه نمی‌گیرد یا pong timeout اعمال نمی‌کند.
  • این نود بایت‌های payload را رمزنگاری، احراز هویت، فشرده یا بازنویسی نمی‌کند.
  • در کنار transport‌هایی که byteهای framed را بین client و server حفظ می‌کنند امن‌ترین است.