Skip to content

Instantly share code, notes, and snippets.

@Luigi-Pizzolito
Created March 19, 2024 13:09
Show Gist options
  • Save Luigi-Pizzolito/e92ddb0691f516a4221c1f77ff9e1a79 to your computer and use it in GitHub Desktop.
Save Luigi-Pizzolito/e92ddb0691f516a4221c1f77ff9e1a79 to your computer and use it in GitHub Desktop.
Go Broadcast, one channel send to many goroutines channel recieve
package main
import "fmt"
// broadcast struct
type broadcast struct {
listeners map[int]chan []byte
}
// NewBroadcast creates a new broadcast instance
func NewBroadcast() *broadcast {
return &broadcast{
listeners: make(map[int]chan []byte),
}
}
// NewListener creates a new listener and returns its channel and member ID
func (b *broadcast) NewListener() (int, chan []byte) {
listener := make(chan []byte)
memberID := len(b.listeners) + 1
b.listeners[memberID] = listener
return memberID, listener
}
// LeaveGroup closes the channel and removes it from the array
func (b *broadcast) LeaveGroup(memberID int) {
if listener, ok := b.listeners[memberID]; ok {
close(listener)
delete(b.listeners, memberID)
}
}
// SendMessage sends a message to all listener channels
func (b *broadcast) SendMessage(message []byte) {
fmt.Println("Sending msg")
for _, listener := range b.listeners {
listener <- message
}
}

BCast

Go Broadcast, one channel send to many goroutines channel recieve

Usage

package main

import (
  "fmt"
  "time"
  "sync
)

var (
  bcast *broadcast
  wg    sync.WaitGroup
)

func main() {
  // Create broadcast group to send the []byte to all subscribed routines
	bcast = NewBroadcast()
  // Start listener routines
  wg.Add(5)
  for i := 0; i < 5; i++ {
    go reciever(i)
  }
  // Send some messages
  for i := 0; i < 5; i++ {
    bcast.SendMessage([]byte("Test Message"))
    time.Sleep(time.Second)
  }
  
  wg.Wait()
}

func reciever(i int) {
  defer wg.Done()
  // Create a new listener to subscribe to the channel
  instanceID, instanceChan := bcast.NewListener()
  // Defer leaving the broadcast group, unsubscribe
	defer bcast.LeaveGroup(instanceID)
  // Listen for messages
  for {
    select {
    case msg <-instanceChan:
      fmt.Printf("Recieved msg from routine %d: %s\n", i, msg)
    }
  }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment