0Pricing
Go Academy · درس

بث الرسائل

أرسل إلى عدة عملاء

بث الرسائل درس مجاني في Go Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Go Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Go Academy 4 دروس في المجموع.

الإرسال إلى عدة عملاء

تحتاج غرف المحادثة والتغذية المباشرة إلى إرسال رسالة واحدة إلى كل عميل متصل. وبما أن كل WebSocket يسمح بكاتب واحد فقط، فأنت بحاجة إلى نمط تنسيق: وهو hub.

نمط Hub

الـ hub هو goroutine مركزي يمتلك مجموعة العملاء وقناة بث. ويسجّل العملاء أنفسهم ويلغون تسجيلهم، بينما يوزّع hub الرسائل عليهم. ولا تصل goroutines متعددة مباشرةً إلى الخريطة المشتركة.

هياكل بيانات Hub

يحتفظ hub بما يلي:

  • مجموعة من العملاء (map[*Client]bool)
  • قناة broadcast للرسائل
  • قناتا register وunregister
type Hub struct {
    clients    map[*Client]bool
    broadcast  chan []byte
    register   chan *Client
    unregister chan *Client
}

حلقة تشغيل Hub

تنتقي goroutine واحدة من نوع Run بين القنوات. وبما أن هذه goroutine وحدها تعدّل الخريطة، فلا حاجة إلى mutex.

func (h *Hub) Run() {
    for {
        select {
        case c := <-h.register:
            h.clients[c] = true
        case c := <-h.unregister:
            delete(h.clients, c)
            close(c.send)
        case msg := <-h.broadcast:
            for c := range h.clients {
                c.send <- msg
            }
        }
    }
}

قناة إرسال لكل عميل

يمتلك كل عميل send chan []byte مخزنة مؤقتًا. يكتب hub فيها، ثم تفرغها goroutine كاتب مخصصة إلى المقبس. وهذا يلتزم بقاعدة الكاتب الواحد.

type Client struct {
    conn *websocket.Conn
    send chan []byte
}

Goroutine الكاتب

يشغّل كل عميل writePump يتنقل عبر send ويكتب إلى المقبس. وعند إغلاق القناة، يرسل إطار إغلاق.

func (c *Client) writePump() {
    for msg := range c.send {
        c.conn.WriteMessage(websocket.TextMessage, msg)
    }
}

تجنّب العملاء البطيئين

إذا كان أحد العملاء بطيئًا، فستمتلئ send المخزنة مؤقتًا الخاصة به. ومن السياسات الشائعة: إذا امتلأت المخزنة المؤقتة، افصل العميل بدلًا من إيقاف hub بالكامل.

select {
case c.send <- msg:
default:
    close(c.send)
    delete(h.clients, c)
}

لماذا القنوات بدلًا من Mutexes

مقولة Go هي: «مشاركة الذاكرة من خلال التواصل». يؤدي تمرير جميع التعديلات عبر goroutine واحدة باستخدام القنوات إلى تجنّب حالات التنافس على خريطة العملاء من دون قفل صريح.

بث رسالة

يمكن لأي معالج إجراء البث بإرسال رسالة عبر قناة hub؛ ويتولى hub توزيعها على كل عميل مسجّل.

hub.broadcast <- []byte("server announcement")

الإرسال الموجّه مقابل البث

بالنسبة إلى الغرف أو الرسائل المباشرة، خزّن العملاء بحسب معرّف الغرفة أو المستخدم، وكرّر العملية على المجموعة الفرعية المعنية فقط بدلًا من جميع العملاء. يحافظ ذلك على كفاءة المحادثة التي تضم غرفًا كثيرة.

قابل للتشغيل: التوزيع باستخدام القنوات

يحاكي هذا البرنامج المستقل hub يوزّع رسالة واحدة على عدة قنوات للعملاء، باستخدام المكتبة القياسية وgoroutines فقط.

package main

import (
    "fmt"
    "sync"
)

func main() {
    clients := []chan string{make(chan string, 1), make(chan string, 1), make(chan string, 1)}
    msg := "hello all"
    for _, c := range clients {
        c <- msg // fan-out
    }
    var wg sync.WaitGroup
    for i, c := range clients {
        wg.Add(1)
        go func(id int, ch chan string) {
            defer wg.Done()
            fmt.Printf("client %d got: %s\n", id, <-ch)
        }(i, c)
    }
    wg.Wait()
}

تحقق سريع

اختبر مدى فهمك للبث.

مراجعة

لقد تعلمت البث إلى عدة عملاء:

  • تمتلك goroutine الخاصة بـ hub مجموعة العملاء وقناة البث
  • يمتلك كل عميل قناة إرسال مخزنة مؤقتًا تفرغها goroutine كاتب
  • يلتزم ذلك بقاعدة الكاتب الواحد لكل اتصال
  • افصل العملاء البطيئين للحفاظ على استجابة hub

الأسئلة الشائعة

هل درس «بث الرسائل» مجاني؟

نعم — نص درس «بث الرسائل» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Go Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Go Academy 4 دروس في المجموع.

ماذا ستتعلم في «بث الرسائل»؟

أرسل إلى عدة عملاء تتمرن على Go Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Go Academy؟

لا تُشترط خبرة سابقة. Go Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.

كم من الوقت يستغرق درس «بث الرسائل»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Go Academy هذا؟

نعم. كل درس في Go Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. أساسيات WebSocket
  2. استخدام gorilla/websocket
  3. بث الرسائل
  4. إدارة الاتصالات
← العودة إلى Go Academy