این داکیومنت، راهنمای جامعی برای پیادهسازی ارتباط WebSocket بین اپلیکیشن موبایل (اندروید و iOS) و تبلت سفارشی را ارائه میدهد. با استفاده از این راهنما، برنامهنویسان قادر خواهند بود یک سیستم ارتباطی پایدار، امن و سریع بین این دو دستگاه از طریق سرور WebSocket پیادهسازی کنند.
این پروتکل ارتباطی برای کنترل تجهیزات هوشمند، خانه هوشمند، سیستمهای مانیتورینگ، کنترل روشنایی، دما، شاتر، ترموستات و سایر مصارف کنترل از راه دور مناسب است.
در این سیستم سه ایستگاه کاری اصلی وجود دارد:
deviceType: '1'
شناخته میشود و دارای شناسه UUID منحصر به فرد است.نکته مهم: سرور WebSocket صرفاً نقش واسط ارتباطی دارد و پیامها را بدون تغییر از منبع به مقصد منتقل میکند. منطق کنترلی و پردازش اصلی در تبلت سفارشی و اپلیکیشن موبایل پیادهسازی میشود.
تمام پیامهای ارسالی و دریافتی با فرمت JSON انجام میشود و شامل فیلدهای زیر است:
فیلد | توضیح | مثال |
---|---|---|
code | کد پیام که نوع عملیات را مشخص میکند | '101'، '201'، '505'، '104' |
sequence | شماره ترتیب پیام که در هر درخواست جدید افزایش مییابد | 0، 1، 2، ... |
sourceId | شناسه فرستنده پیام | '5f3c6d61-434e-f64a-fcfa-b645a5637386' |
targetId | شناسه گیرنده پیام | '688d2452-cf85-d16b-a094-c57e8b81347b' |
time | زمان ارسال پیام (میلیثانیه) | 1503 |
type | نوع پیام | 'com.astrum.websocket.JSONRequest' |
deviceType | نوع دستگاه (برای موبایل: '1') | '1' |
deviceName | نام دستگاه | 'M2101K6G-Xiaomi' |
connectType | نوع اتصال | 3 |
ipSrc | آدرس IP مبدا | '2.144.3.143' |
iptrg | آدرس IP مقصد | '2.144.3.143' |
message | محتوای اصلی پیام (در صورت نیاز) | آبجکت JSON |
مثال یک پیام درخواست از اپ موبایل به تبلت:
{ "deviceType": "1", "sequence": 0, "code": "101", "targetId": "688d2452-cf85-d16b-a094-c57e8b81347b", "time": 1503, "type": "com.astrum.websocket.JSONRequest", "deviceName": "M2101K6G-Xiaomi", "connectType": 3, "ipSrc": "2.144.3.143", "sourceId": "5f3c6d61-434e-f64a-fcfa-b645a5637386", "iptrg": "2.144.3.143" }
مثال پیام پاسخ از تبلت به اپ موبایل:
{ "targetId": "5f3c6d61-434e-f64a-fcfa-b645a5637386", "time": 8305688, "type": "com.lotus.websocket.JSONResponse", "code": "505", "sequence": 835, "connectType": 1, "ipSrc": "2.144.3.143", "sourceId": "688d2452-cf85-d16b-a094-c57e8b81347b", "iptrg": "2.144.3.143" }
کدهای پیام زیر برای ارتباط بین اپلیکیشن موبایل و تبلت سفارشی استفاده میشود:
کد | نوع پیام | توضیح |
---|---|---|
100 | مانیتورینگ-داده | ارسال وضعیت مقدار یک کنترل یا پورت (مثل دما، روشن/خاموش، فعال/غیرفعال) توسط تبلت سفارشی |
101 | درخواست ثبت مانیتورینگ | درخواست برقراری ارتباط با تبلت یا درخواست دریافت کل مقادیر برای کنترلها و پورتها |
102 | درخواست لغو مانیتورینگ | درخواست برای لغو مانیتورینگ در وضعیت ثبت نشده |
103 | بررسی درخواست هدف | درخواست بررسی هدف یا اطمینان از اتصال برای دریافت پاسخ 203 با پیام ready |
104 | نوشتن وضعیت | درخواست اپ برای تغییر مقدار یک کنترل یا یک پورت |
201 | پاسخ ثبت دستگاه | پاسخ تبلت برای تایید دسترسی در مورد درخواست 101 و ارسال کلی وضعیت مقادیر کنترلها و پورتها |
202 | پاسخ لغو مانیتورینگ | پاسخ درخواست 102 در وضعیت ثبت نشده |
203 | بررسی پاسخ هدف | پیام تبلت برای اعلام در حال مطالعه و تهیه خروجی پاسخ 201 یا پاسخ به درخواست 103 |
303 | درخواست داده | ارسال درخواست کوئری برای استخراج از دیتابیس از سمت اپ موبایل |
304 | پاسخ داده | پاسخ درخواست 303 ارسالی توسط تبلت سفارشی |
404 | قطع ارتباط | اعلام قطع ارتباط |
503 | رد دسترسی | دسترسی رد شده توسط کاربر |
505 | در انتظار مجوز | پاسخ تبلت برای اعلام انتظار تا تایید یا رد مجوز برای درخواست 101 |
1100 | پیام VOIP | ارتباط صوتی |
1101 | پیام دوربین | ارتباط تصویری |
هشدار: همه کدهای پیام به صورت رشته (String) ارسال میشوند، نه به صورت عدد. مثلاً "101"
به جای 101
.
روند کلی ارتباط و احراز هویت بین اپلیکیشن موبایل و تبلت سفارشی به شرح زیر است:
'101'
(درخواست ثبت مانیتورینگ) به سرور WebSocket ارسال میکند.'505'
(در انتظار مجوز) برای اپ موبایل میفرستد.'101'
را ارسال کرده و این چرخه تا تایید یا رد قطعی توسط کاربر تبلت ادامه مییابد.'201'
(پاسخ ثبت) همراه با لیست کامل آیتمها و مقادیر آنها به اپ ارسال میشود.'503'
(رد دسترسی) به اپ ارسال میشود.'103'
(بررسی درخواست هدف) به تبلت ارسال میکند و تبلت با کد '203'
(پاسخ ready) پاسخ میدهد.مثال روند احراز هویت:
درخواست ثبت مانیتورینگ از اپ موبایل:
{ "deviceType": "1", "sequence": 0, "code": "101", "targetId": "688d2452-cf85-d16b-a094-c57e8b81347b", "time": 1503, "type": "com.astrum.websocket.JSONRequest", "deviceName": "M2101K6G-Xiaomi", "connectType": 3, "ipSrc": "2.144.3.143", "sourceId": "5f3c6d61-434e-f64a-fcfa-b645a5637386", "iptrg": "2.144.3.143" }
پاسخ انتظار مجوز از تبلت سفارشی:
{ "targetId": "5f3c6d61-434e-f64a-fcfa-b645a5637386", "time": 8305688, "type": "com.lotus.websocket.JSONResponse", "code": "505", "sequence": 835, "connectType": 1, "ipSrc": "2.144.3.143", "sourceId": "688d2452-cf85-d16b-a094-c57e8b81347b", "iptrg": "2.144.3.143" }
تایید دسترسی و ارسال اطلاعات ایتمها از تبلت:
{ "targetId": "5f3c6d61-434e-f64a-fcfa-b645a5637386", "time": 10308775, "message": [ { "id": "5f8396c6-369d-45bd-ac3b-02ea27494682", "value": null }, { "id": "be0727b7-6cca-4b5e-8b9f-881a312e9355", "value": null }, { "id": "237697c2-9815-4b8e-b145-9b9798214390", "value": "1" }, // صدها مورد دیگر ], "deviceInfo": { "deviceId": "L000A0924303B9", "screensaver_timeout": 60, "soundLevel": 50, // اطلاعات دستگاه }, "type": "com.lotus.websocket.JSONResponse", "sequence": 856, "code": "201", "connectType": 1, "ipSrc": "2.144.3.143", "sourceId": "688d2452-cf85-d16b-a094-c57e8b81347b", "iptrg": "2.144.3.143" }
نکته: در صورت عدم پاسخ از سوی کاربر، سیستم تا حداکثر 15 بار پیام را با sequence متفاوت تکرار میکند. پس از آن اپلیکیشن باید مجدداً درخواست را ارسال کند.
پس از برقراری ارتباط، اپلیکیشن موبایل میتواند آیتمهای مختلف را کنترل کند. این کنترل از طریق ارسال پیام با کد '104'
(نوشتن وضعیت) انجام میشود و تبلت وضعیت بهروزرسانی شده را با کد '100'
(مانیتورینگ-داده) باز میگرداند.
انواع آیتمهای قابل کنترل:
نوع آیتم | نوع داده (type) | مقدار (value) |
---|---|---|
سوییچ/کلید | INTEGER | '0' (خاموش)، '1' (روشن) |
لوستر | INTEGER | '0' (خاموش)، '1' (روشن) |
شاتر | INTEGER | '0' (متوقف)، '1' (باز)، '2' (بسته) |
دیمر | INTEGER | مقداری بین '0' تا '100' برای شدت نور |
RGB کنترل | INTEGER | مقادیر رنگ (مثلا '32'، 'FF'، 'CCFFFFFF') |
ترموستات - مد | MODE | 'Heat'، 'Cool'، 'Auto'، 'Frost_Protection' |
ترموستات - فن | FAN_SPEED | 'Low'، 'Medium'، 'High'، 'Auto' |
ترموستات - دما | DOUBLE | '1.0'، '24.5'، '35.23' |
مثالهای کنترل آیتمها:
روشن کردن یک کلید:
{ "sequence": 6, "code": "104", "targetId": "688d2452-cf85-d16b-a094-c57e8b81347b", "time": 8088, "message": { "force": false, "id": "23ace3e0-92b8-43f0-8c49-6bf365fdede3", "type": "INTEGER", "value": "1" }, "type": "com.astrum.websocket.JSONRequest", "connectType": 3, "ipSrc": "2.144.3.143", "sourceId": "5f3c6d61-434e-f64a-fcfa-b645a5637386", "iptrg": "2.144.3.143" }
تغییر مود ترموستات:
{ "sequence": 223, "code": "104", "targetId": "688d2452-cf85-d16b-a094-c57e8b81347b", "time": 8741, "message": { "force": false, "id": "c8b5a21f-44fc-4c41-a2b3-aa5ec39eb201", "type": "MODE", "value": "Frost_Protection" }, "type": "com.astrum.websocket.JSONRequest", "connectType": 3, "ipSrc": "2.144.3.143", "sourceId": "5f3c6d61-434e-f64a-fcfa-b645a5637386", "iptrg": "2.144.3.143" }
تغییر سرعت فن ترموستات:
{ "sequence": 378, "code": "104", "targetId": "688d2452-cf85-d16b-a094-c57e8b81347b", "time": 9568, "message": { "force": false, "id": "6b37308e-b18d-4be7-8cc8-6b98c875f322", "type": "FAN_SPEED", "value": "High" }, "type": "com.astrum.websocket.JSONRequest", "connectType": 3, "ipSrc": "2.144.3.143", "sourceId": "5f3c6d61-434e-f64a-fcfa-b645a5637386", "iptrg": "2.144.3.143" }
مثال پاسخ وضعیت (مانیتورینگ-داده):
{ "targetId": "5f3c6d61-434e-f64a-fcfa-b645a5637386", "time": 10325345, "message": { "force": false, "id": "66047347-3b5b-4817-8713-a3bf8d1ab546", "value": "35.47" }, "type": "com.lotus.websocket.JSONResponse", "sequence": 866, "code": "100", "connectType": 1, "ipSrc": "2.144.3.143", "sourceId": "688d2452-cf85-d16b-a094-c57e8b81347b", "iptrg": "2.144.3.143" }
اپلیکیشن موبایل میتواند با ارسال پیام با کد '303'
(درخواست داده)، کوئریهایی را برای استخراج اطلاعات از دیتابیس تبلت ارسال کند. تبلت سفارشی نتیجه کوئری را با کد '304'
(پاسخ داده) بازگرداند.
مثال ارسال کوئری برای دریافت دسترسیها:
{ "sequence": 2, "code": "303", "targetId": "688d2452-cf85-d16b-a094-c57e8b81347b", "time": 4638, "message": { "queryLocal": "select * from tb_permission WHERE push_token = ''" }, "type": "com.astrum.websocket.JSONRequest", "sequenceId": 1, "connectType": 3, "ipSrc": "2.144.3.143", "sourceId": "5f3c6d61-434e-f64a-fcfa-b645a5637386", "iptrg": "2.144.3.143" }
مثال پاسخ کوئری:
{ "targetId": "5f3c6d61-434e-f64a-fcfa-b645a5637386", "sequenceId": 1, "time": 10309477, "message": { "sequenceId": 1, "queryResult": [ {...} ] }, "type": "com.lotus.websocket.JSONResponse", "sequence": 857, "code": "304", "connectType": 1, "ipSrc": "2.144.3.143", "sourceId": "688d2452-cf85-d16b-a094-c57e8b81347b", "iptrg": "2.144.3.143" }
مثال ارسال کوئری برای دریافت سناریوها:
{ "sequence": 3, "code": "303", "targetId": "688d2452-cf85-d16b-a094-c57e8b81347b", "time": 4834, "message": { "queryLocal": "select * from tb_scenarios" }, "type": "com.astrum.websocket.JSONRequest", "sequenceId": 2, "connectType": 3, "ipSrc": "2.144.3.143", "sourceId": "5f3c6d61-434e-f64a-fcfa-b645a5637386", "iptrg": "2.144.3.143" }
نکته: فیلد sequenceId
برای ردیابی کوئریهای مختلف استفاده میشود. این فیلد در پاسخ نیز بازگردانده میشود تا اپلیکیشن بتواند تشخیص دهد این پاسخ مربوط به کدام کوئری است.
برای حفظ امنیت ارتباط بین اپلیکیشن موبایل و تبلت سفارشی، موارد زیر را در نظر بگیرید:
هشدار امنیتی: هرگز کوئریهای دیتابیس را بدون اعتبارسنجی و فیلتر کردن اجرا نکنید. این کار میتواند منجر به حملات SQL Injection شود.
برای بهینهسازی عملکرد و افزایش پایداری ارتباط، موارد زیر را در نظر بگیرید:
نکته: برای کاهش بار شبکه، تنها تغییرات وضعیت را ارسال کنید، نه تمام آیتمها را در هر بهروزرسانی.
برای پیادهسازی WebSocket در اندروید، میتوانید از کتابخانههای زیر استفاده کنید:
نکات مهم پیادهسازی:
onResume()
باز کنید و در onPause()
یا onStop()
ببندید.WakeLock
برای جلوگیری از قطع ارتباط در حالت خواب دستگاه استفاده کنید.نکته: شماره sequence
پیامها باید به صورت تصاعدی افزایش یابد. این شماره را در حافظه نگه دارید و در هر بار ارسال پیام، آن را افزایش دهید.
برای پیادهسازی WebSocket در iOS، میتوانید از کتابخانههای زیر استفاده کنید:
نکات مهم پیادهسازی:
viewDidAppear()
باز کنید و در viewDidDisappear()
ببندید.URLSession
با کانفیگ background
برای حفظ ارتباط در پسزمینه استفاده کنید.applicationDidEnterBackground
و applicationWillEnterForeground
ارتباط را به درستی مدیریت کنید.Grand Central Dispatch
برای پردازش غیرهمزمان پیامها استفاده کنید.نکته: از NSUserDefaults
برای ذخیره deviceId
و sourceId
استفاده کنید تا در اجراهای بعدی اپلیکیشن، نیاز به ثبت مجدد نباشد.
برای پیادهسازی بهینه و کارآمد، موارد زیر را رعایت کنید:
هشدار: هرگز اطلاعات حساس را به صورت متن ساده (plain text) از طریق WebSocket ارسال نکنید. در صورت نیاز از رمزنگاری سمت کلاینت استفاده کنید.
خطاهای رایج و راهحلهای آنها:
مشکل | علت احتمالی | راه حل |
---|---|---|
عدم برقراری ارتباط | آدرس نادرست یا مشکل شبکه | بررسی آدرس سرور WebSocket و وضعیت شبکه |
قطع مکرر ارتباط | مشکل شبکه یا تایماوت | اتصال مجدد خودکار و افزایش زمان تایماوت |
عدم دریافت پاسخ | مشکل در ساختار پیام یا شناسهها | بررسی صحت sourceId، targetId و ساختار پیام |
خطای دسترسی | عدم تایید کاربر یا منقضی شدن مجوز | ارسال مجدد درخواست ثبت (کد 101) |
تاخیر در دریافت پاسخ | کندی شبکه یا پردازش سنگین | استفاده از تایماوت و مدیریت حالتهای انتظار |
ناسازگاری در وضعیت آیتمها | از دست رفتن پیامها یا تاخیر | ارسال درخواست بروزرسانی کلی وضعیت (کد 101) |
روند عیبیابی:
نکته: از ابزارهایی مانند Wireshark یا Charles Proxy برای نظارت بر ترافیک WebSocket و عیبیابی دقیقتر استفاده کنید.