实现多goroutine之间的发布和订阅
一、实现思路
- 一个发布者,三个订阅者
- 发布者需要跟每个订阅者之间,都要建立一个chan
- 调用发布方法后,三个订阅者都能收到发布的信息
- 在发布和接收之间,增加暂停,使运行结果更加直观
二、实现代码
func Test_Main(t *testing.T) {
sl := NewSubList()
// 增加A的订阅
sl.Subscribe("A", make(Broadcast))
// 增加B的订阅
sl.Subscribe("B", make(Broadcast))
// 增加C的订阅
sl.Subscribe("C", make(Broadcast))
Sleep(3)
sl.PublishMessage("Hello World!")
Sleep(3)
sl.PublishMessage("Golang very good!")
sl.Unsubscribe("B")
Sleep(3)
sl.PublishMessage("Golang so easy!")
}
type Broadcast chan string
type SubList struct {
CH map[string]Broadcast
sync.RWMutex
}
func NewSubList() *SubList {
s := &SubList{}
s.CH = make(map[string]Broadcast) //所有channel
return s
}
// Subscribe 订阅
func (s *SubList) Subscribe(name string, bc Broadcast) {
s.Lock()
s.CH[name] = bc
s.Unlock()
go s.ListeningBroadcast(name, bc)
}
// Unsubscribe 取消订阅
func (s *SubList) Unsubscribe(name string) {
s.Lock()
delete(s.CH, name)
s.Unlock()
}
//发布消息
func (s *SubList) PublishMessage(message string) {
s.RLock()
for k, v := range s.CH {
v <- message
fmt.Println("向 ", k, " 发送 ", message)
}
s.RUnlock()
}
// ListeningBroadcast 监听信息
func (s *SubList) ListeningBroadcast(name string, bc Broadcast) {
for {
message := <-bc
time.Sleep(time.Duration(1) * time.Second)
fmt.Println(name, " 收到 ", message)
}
}
func Sleep(i int64) {
fmt.Println("等待3秒......")
time.Sleep(time.Duration(i) * time.Second)
}