WebSocket في Go: مكتبة gorilla/websocket والتنفيذ القياسي

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

مكتبة WebSocket في Go (Golang): gorilla/websocket و net/http القياسي



WebSocket هو بروتوكول يوفر اتصالاً ثنائي الاتجاه بالكامل بين العميل والخادم عبر اتصال TCP واحد طويل الأمد. على عكس HTTP التقليدي، بعد إنشاء الاتصال، يمكن نقل البيانات في كلا الاتجاهين في أي وقت، دون الحاجة إلى طلبات مستمرة من العميل. هذا هو الحل الأمثل للدردشات، الإشعارات في الوقت الفعلي، الألعاب عبر الإنترنت، ومنصات التداول.



في نظام Go (Golang)، توجد عدة طرق للعمل مع WebSocket. المكتبة الأكثر شهرة والمختبرة عبر الزمن هي gorilla/websocket. ومع ذلك، بدءًا من Go 1.22، أصبح من الممكن تنفيذ خادم WebSocket أساسي بدون تبعيات خارجية، باستخدام الحزمة القياسية net/http. في هذه المقالة، سنشرح بالتفصيل كلا النهجين.



تثبيت مكتبة gorilla/websocket



للبدء مع gorilla/websocket، قم بتثبيتها عبر go get:



go get github.com/gorilla/websocket


توفر المكتبة واجهة برمجة تطبيقات (API) ملائمة لإنشاء كل من الجانب الخادم والعميل. فهي تتعامل مع المصافحة (handshake)، تأطير الرسائل، تدعم الضغط، والـ ping/pong التلقائي.



خادم WebSocket باستخدام gorilla/websocket



لننظر إلى مثال لخادم صدى بسيط. يرسل العميل رسالة، ويعيدها الخادم إليه:



package main

import ( "log" "net/http" "github.com/gorilla/websocket")

var upgrader = websocket.Upgrader{ CheckOrigin: func(r *http.Request) bool { return true // السماح بأي مصادر (للتطوير) },}

func echoHandler(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("/echo", echoHandler) log.Fatal(http.ListenAndServe(":8080", nil))}


هنا، يقوم Upgrader بتحويل طلب HTTP عادي إلى اتصال WebSocket. تتحكم الدالة CheckOrigin في المجالات المسموح لها بالاتصال. في الإنتاج، يُوصى بالتحقق من مصادر محددة.



عميل WebSocket باستخدام gorilla/websocket



مثال لعميل يتصل بخادمنا ويرسل رسالة:



package main

import ( "log" "os" "os/signal" "time" "github.com/gorilla/websocket")

func main() { interrupt := make(chan os.Signal, 1) signal.Notify(interrupt, os.Interrupt)

url := "ws://localhost:8080/echo" c, _, err := websocket.DefaultDialer.Dial(url, nil) if err != nil { log.Fatal("اتصال:", err) } defer c.Close()

done := make(chan struct{})

// Goroutine لقراءة الردود go func() { defer close(done) for { _, message, err := c.ReadMessage() if err != nil { log.Println("قراءة:", err) return } log.Printf("استقبال: %s", message) } }()

// إرسال رسالة ticker := time.NewTicker(time.Second) defer ticker.Stop()

for { select { case <-done: return case t := <-ticker.C: err := c.WriteMessage(websocket.TextMessage, []byte(t.String())) if err != nil { log.Println("كتابة:", err) return } case <-interrupt: log

توصيات