WebSocket في Go: بناء تطبيقات الزمن الفعلي مع Golang
تتطلب تطبيقات الويب الحديثة بشكل متزايد نقل بيانات فوري بين العميل والخادم. نموذج الطلب-الاستجابة التقليدي (HTTP) غير مناسب للمحادثات والألعاب عبر الإنترنت ومنصات التداول والمراقبة في الزمن الفعلي. يأتي بروتوكول WebSocket للإنقاذ، حيث ينشئ اتصالاً ثنائي الاتجاه ثابتاً. في هذه المقالة على pythonlib.ru، سنستكشف كيفية بناء تطبيق زمن فعلي بلغة Go (Golang) باستخدام WebSocket.
تعتبر Go مثالية لهذه المهمة بفضل دعمها المدمج للتوازي (goroutines والقنوات) والأداء العالي. معاً، سنكتب خادم WebSocket بسيط، وننفذ غرفة محادثة، ونلقي نظرة على المشكلات النموذجية.
ما هو WebSocket ولماذا هو مطلوب في Go؟
WebSocket هو بروتوكول يعمل عبر TCP. يبدأ بطلب HTTP (مصافحة)، وبعدها يتم "ترقية" الاتصال إلى قناة ثنائية الاتجاه ثابتة. على عكس long polling أو Server-Sent Events، يسمح WebSocket للخادم والعميل بإرسال البيانات في أي وقت دون إعادة إنشاء الاتصال.
مزايا استخدام WebSocket في Go:
- التوازي: تتعامل goroutines بسهولة مع آلاف الاتصالات المتزامنة.
- الأداء: استهلاك ضئيل للذاكرة لكل اتصال.
- البساطة: مكتبة
net/httpالقياسية وحزمةgorilla/websocketتجعل الكود موجزاً.
يُستخدم WebSocket غالباً في:
- أنظمة الدردشة والمراسلة
- المحررات عبر الإنترنت (مثل Google Docs)
- محطات التداول (أسعار الأسهم)
- الألعاب والمحاكيات
تثبيت وإعداد WebSocket في Go
لا تحتوي Go على دعم مدمج لـ WebSocket في المكتبة القياسية، لكن هناك حزمة ممتازة gorilla/websocket. لنتثبيتها:
go get github.com/gorilla/websocketلننشئ خادم HTTP أدنى من شأنه التعامل مع اتصالات WebSocket. أولاً، سنكتب دالة معالجة "تُرقّي" طلب HTTP إلى WebSocket.
package main
import ( "log" "net/http" "github.com/gorilla/websocket")
var upgrader = websocket.Upgrader{ CheckOrigin: func(r *http.Request) bool { return true // السماح بجميع المصادر (للتطوير) },}
func handleWebSocket(w http.ResponseWriter, r *http.Request) { conn, err := upgrader.Upgrade(w, r, nil) if err != nil { log.Print("خطأ في الترقية:", err) return } defer conn.Close()
// حلقة لا نهائية لقراءة الرسائل for { messageType, message, err := conn.ReadMessage() if err != nil { log.Println("خطأ في القراءة:", err) break } log.Printf("تم الاستلام: %s", message)
// استجابة الصدى: إرجاع نفس الرسالة if err := conn.WriteMessage(messageType, message); err != nil { log.Println("خطأ في الكتابة:", err) break } }}
func main() { http.HandleFunc("/ws", handleWebSocket) log.Println("تم بدء الخادم على المنفذ :8080") log.Fatal(http.ListenAndServe(":8080", nil))}يقوم هذا الكود بإنشاء خادم صدى بسيط. يتصل العميل بـ ws://localhost:8080/ws ويستقبل جميع الرسائل المرسلة مرة أخرى.
إنشاء غرفة محادثة زمن فعلي في Go باستخدام WebSocket
الآن لنجعل الأمر أكثر تعقيداً: سننشئ غرفة محادثة يمكن لجميع العملاء المتصلين رؤية رسائل بعضهم البعض. لهذا، نحتاج إلى إدارة قائمة الاتصالات وبث الرسائل.
المكونات الرئيسية:
- Hub — مدير مركزي يقوم بتسجيل/إزالة العملاء وبث الرسائل.
- Client — يمثل اتصال WebSocket فردياً.