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"
}
فیلدهای اجباری
فیلدهای سطح اصلی:
| فیلد | نوع | توضیح |
|---|---|---|
name | string | نام یکتای نود در پیکربندی. |
type | string | باید دقیقاً "KeepAliveServer" باشد. |
settings | object | اختیاری. پیادهسازی فعلی تنظیم اختصاصی برای سرور ندارد. |
next | string | در استفاده عادی اجباری است. نود بعدی payloadهای decodeشده upstream را میگیرد. |
KeepAliveServer باید نود قبلی داشته باشد و توسط KeepAliveClient متناظر قابل دسترس باشد.
تنظیمات
KeepAliveServer در حال حاضر تنظیم معنیداری ندارد. زمانبندی keepalive در KeepAliveClient با settings.ping-interval تنظیم میشود.
فرمت Frame
سرور از همان prefix سهبایتی client استفاده میکند:
| Bytes | فیلد | توضیح |
|---|---|---|
0..1 | body length | عدد صحیح unsigned و 16-bit با ترتیب big-endian. این طول شامل بایت type فریم بهعلاوه بایتهای payload است. |
2 | frame kind | 1 payload عادی، 2 ping، یا 3 pong. |
نوعهای frame:
| Kind | معنی | Body payload |
|---|---|---|
1 | payload عادی | بایتهای payload اصلی WaterWall. |
2 | ping | در ترافیک keepalive عادی خالی است. |
3 | pong | پاسخ خالی به یک 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 Finish | state محلی را از بین میبرد و سپس Finish را به next میفرستد. |
downstream Payload | payload را در یک یا چند فریم عادی encode و به نود قبلی ارسال میکند. بافر payloadهای خالی برای استفاده مجدد برمیگردد. |
downstream Est / Pause / Resume | به نود قبلی فرستاده میشوند. |
downstream Finish | state محلی را از بین میبرد و سپس 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 حفظ میکنند امنترین است.