مقدمة: لماذا WebSocket و Kotlin هما الثنائي المثالي للتطبيقات الفورية (real-time)
تتطلب تطبيقات الويب الحديثة بشكل متزايد نقلًا فوريًا للبيانات: بدءًا من غرف الدردشة والألعاب عبر الإنترنت وصولًا إلى أسعار البورصة وأنظمة المراقبة. بروتوكول HTTP التقليدي بنموذج الطلب والاستجابة الخاص به غير فعال لمثل هذه المهام - فهو يُحدث تأخيرات وحركة مرور زائدة. هنا يأتي دور WebSocket - وهو بروتوكول يوفر اتصالًا ثنائي الاتجاه دائمًا بين العميل والخادم.
تعتبر لغة Kotlin بفضل تركيبها المختصر، وتوافقها الكامل مع Java، ودعمها القوي للكوروتينات (coroutines) مثالية لبناء تطبيقات فورية (real-time). إطار العمل Ktor من JetBrains يوفر دعمًا مدمجًا لـ WebSocket، مما يسمح بكتابة كود فعال وآمن حرفيًا في بضعة أسطر.
في هذه المقالة، سنشرح كيفية بناء تطبيق فوري (real-time) كامل بلغة Kotlin باستخدام WebSocket. ستتعلم:
- كيفية إعداد خادم WebSocket على Ktor
- كيفية الاتصال به من متصفح أو تطبيق جوال
- كيفية تنظيم تبادل الرسائل في الوقت الفعلي
- ما هي الأنماط (patterns) والمناهج التي يجب استخدامها للتوسع
1. أساسيات WebSocket ومزاياه في Kotlin
ما هو WebSocket؟
WebSocket هو بروتوكول يعمل فوق TCP. بعد إنشاء الاتصال عبر مصافحة HTTP (upgrade)، يمكن للعميل والخادم تبادل البيانات في كلا الاتجاهين دون طلبات متكررة. هذا يقلل بشكل جذري من زمن الوصول (latency) ويخفف الحمل على الشبكة.
لماذا Kotlin؟
- الكوروتينات - تسمح بمعالجة آلاف اتصالات WebSocket المتزامنة دون حظر الخيوط (threads).
- Ktor - إطار عمل غير متزامن (asynchronous) خفيف الوزن مع دعم أصلي لـ WebSocket.
- أمان الأنواع (Type safety) - أخطاء في مرحلة الترجمة (compile time) وليس في وقت التشغيل (runtime).
- تعدد المنصات (Multiplatform) - يمكن لنفس الكود العمل على JVM و JS و Native.
2. إنشاء خادم WebSocket على Ktor
الخطوة 1: إعداد المشروع
أضف التبعيات (dependencies) في ملف build.gradle.kts:
dependencies { implementation("io.ktor:ktor-server-core:2.3.0") implementation("io.ktor:ktor-server-netty:2.3.0") implementation("io.ktor:ktor-server-websockets:2.3.0") implementation("ch.qos.logback:logback-classic:1.4.11")}الخطوة 2: خادم أساسي مع WebSocket
import io.ktor.server.engine.*import io.ktor.server.netty.*import io.ktor.server.websocket.*import io.ktor.websocket.*import kotlinx.coroutines.delay
fun main() { embeddedServer(Netty, port = 8080) { install(WebSockets) webSocket("/chat") { send(Frame.Text("مرحبًا بك في الدردشة!")) for (frame in incoming) { if (frame is Frame.Text) { val text = frame.readText() println("تم الاستلام: $text") send(Frame.Text("الصدى: $text")) } } } }.start(wait = true)}هذا الكود ينشئ خادم صدى (echo) بسيط. عند الاتصال، يتلقى العميل رسالة ترحيب، ويتم إرجاع كل رسالة يرسلها مع البادئة "الصدى:".
الخطوة 3: معالجة عدة عملاء والبث الجماعي
للدردشة الفورية (real-time)، تحتاج إلى تخزين قائمة الجلسات النشطة:
import io.ktor.server.engine.*import io.ktor.server.netty.*import io.ktor.server.websocket.*import io.ktor.websocket.*import kotlinx.coroutines.channels.ConcurrentHashMap
val clients = ConcurrentHashMap<String, WebSocketSession>()
fun main() { embeddedServer(Netty, port = 8080) { install(WebSockets) webSocket("/chat") { val userName = "User_${System.currentTimeMillis()}" clients[userName] = this try {