بث الرسائل
أرسل إلى عدة عملاء
بث الرسائل درس مجاني في 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 يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.