// 3.5 发布订阅模型
package mainimport ("fmt""strings""sync""time"
)type (subscriber chan interface{}         // 订阅者为一个通道topicFunc  func(v interface{}) bool // 主题为一个过滤器
)// 发布者对象
type Publisher struct {m           sync.RWMutex             //读写锁buffer      int                      // 订阅队列的缓存大小timeout     time.Duration            // 发布超时时间subscribers map[subscriber]topicFunc // 订阅者信息
}// 构建一个发布者对象,可以设置发布超时时间和缓存队列的长度
func NewPublisher(publishTimeout time.Duration, buffer int) *Publisher {return &Publisher{buffer:      buffer,timeout:     publishTimeout,subscribers: make(map[subscriber]topicFunc),}}// 关闭发布者对象,同时关闭所有的订阅通道
func (p *Publisher) Close() {p.m.Lock()defer p.m.Unlock()for sub := range p.subscribers {delete(p.subscribers, sub)close(sub)}
}// 添加一个新的订阅者,订阅过滤器筛选后的主题
func (p *Publisher) SubscribeTopic(topic topicFunc) chan interface{} {ch := make(chan interface{}, p.buffer)p.m.Lock()p.subscribers[ch] = topicp.m.Unlock()return ch
}// 添加一个新的订阅者,订阅全部主题
func (p *Publisher) Subscribe() chan interface{} {return p.SubscribeTopic(nil)
}// 退出订阅
func (p *Publisher) Evict(sub chan interface{}) {p.m.Lock()defer p.m.Unlock()delete(p.subscribers, sub)close(sub)
}// 发送主题,可以容忍一定的超时
func (p *Publisher) sendTopic(sub subscriber, topic topicFunc, v interface{}, wg *sync.WaitGroup,
) {defer wg.Done()if topic != nil && !topic(v) { // 过滤信息return}select {case sub <- v:case <-time.After(p.timeout): // 超时}
}// 发布一个主题
func (p *Publisher) Publish(v interface{}) {p.m.Lock()defer p.m.Unlock()var wg sync.WaitGroupfor sub, topic := range p.subscribers {wg.Add(1)go p.sendTopic(sub, topic, v, &wg)}wg.Wait()
}func main() {p := NewPublisher(100*time.Millisecond, 10)defer p.Close()all := p.Subscribe()golang := p.SubscribeTopic(func(v interface{}) bool {if s, ok := v.(string); ok {return strings.Contains(s, "golang")}return false})p.Publish("hello world")p.Publish("hello, golang")go func() {for msg := range all {fmt.Println("all:", msg)}}()go func() {for msg := range golang {fmt.Println("golang:", msg)}}()// 运行一段时间后退出time.Sleep(3 * time.Second)
}

go - 发布订阅模型相关推荐

  1. kafka 发布订阅_在Kafka中发布订阅模型

    kafka 发布订阅 这是第四个柱中的一系列关于同步客户端集成与异步系统( 1, 2, 3 ). 在这里,我们将尝试了解Kafka的工作方式,以便正确利用其发布-订阅实现. 卡夫卡概念 根据官方文件 ...

  2. 在Kafka中发布订阅模型

    这是第四个柱中的一系列关于同步客户端集成与异步系统( 1, 2, 3 ). 在这里,我们将尝试了解Kafka的工作方式,以便正确利用其发布-订阅实现. 卡夫卡概念 根据官方文件 : Kafka是一种分 ...

  3. java实现rabbitmq发布/订阅模型(Publish/Subscribe queues), 生产者 消费者 交换机 消息队列

    发布/订阅模型又称扇出模型,或者是广播模型,可以有多个消费者,每个消费者有自己的队列,每个队列都要绑定到交换机,生产者发送的消息只需要发送到交换机,再由交换机决定要发送到哪些队列,生产者无法自行决定. ...

  4. 分布式发布订阅模型网络的实现有哪些

    大数据中常用的分布式发布订阅系统: 参考资料: WCF百科介绍 分布式"消息发布者-订阅者"模型的实现--WCF双工通讯特性的应用 [设计模式] 观察者模式(发布-订阅/Publi ...

  5. 3,ActiveMQ-入门(基于JMS发布订阅模型)

    一.Pub/Sub-发布/订阅消息传递模型 在发布/订阅消息模型中,发布者发布一个消息,该消息通过topic传递给所有的客户端.在这种模型中,发布者和订阅者彼此不知道对方,是匿名的且可以动态发布和订阅 ...

  6. ros 单向通讯 talker,listener 发布订阅模型

    原文链接: ros 单向通讯 talker,listener 发布订阅模型 上一篇: VirtualBox 端口转发(端口映射) 主机和虚拟机相互访问 下一篇: python 串口编程 发布订阅模型 ...

  7. vue发布订阅模式,发布订阅模型

    1.什么是发布订阅模式 (又叫做观察者模式) 他定义了对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于他的对象都将得到通知. 2.发布订阅模型 1.发布者会给订阅者提供一个方法以便 ...

  8. c#事件的发布-订阅模型_C# 委托和事件 与 观察者模式(发布-订阅模式)讲解 by天命...

    使用面向对象的思想 用c#控制台代码模拟猫抓老鼠 我们先来分析一下猫抓老鼠的过程 1.猫叫了 2.所有老鼠听到叫声,知道是哪只猫来了 3.老鼠们逃跑,边逃边喊:"xx猫来了,快跑啊!我是老鼠 ...

  9. c#事件的发布-订阅模型_NET Core 3 WPF MVVM框架 Prism系列之事件聚合器

    本文将介绍如何在.NET Core3环境下使用MVVM框架Prism的使用事件聚合器实现模块间的通信 一.事件聚合器#  在上一篇 .NET Core 3 WPF MVVM框架 Prism系列之模块化 ...

  10. c#事件的发布-订阅模型_C#事件订阅发布实现原理详解

    我们用一个简单的例子,来说明一下这种消息传递的机制. 有一家三口,妈妈负责做饭,爸爸和孩子负责吃...将这三个人,想象成三个类. 妈妈有一个方法,叫做"做饭".有一个事件,叫做&q ...

最新文章

  1. python迷宫万花筒代码_利用广度优先遍历搜索迷宫的python源代码
  2. 【转】DHCP工作过程详解
  3. c语言中的static变量和static函数
  4. SDUT1281Cup
  5. 怎样从frm ibd恢复mysql_怎样从frm,ibd恢复MYSQL
  6. unity摄影机depth模式_Unity3D Camera 摄像机属性详解
  7. 网上科学计算机,【图片】计算机-科普—都是从网上找的【计算机科学与技术吧】_百度贴吧...
  8. oracle外关联更新操作,记要oracle 关联更新的例子
  9. MySQL数据类型不一致_数据类型不一致导致的SQL不走索引
  10. 一步一步写算法(之循环和递归)
  11. MFC入门示例之静态文本框、编辑框
  12. FLASH AS3 TextField
  13. PhoneGap的Android端插件开发
  14. Apache mod_rewrite
  15. python工资条教程_批量发工资怎么操作_利用python轻松解决用邮箱批量发工资条...
  16. 虚幻引擎编程基础(二)
  17. png变成矢量图_ps中如何在将图转换成矢量图
  18. 大华中心管理服务器,大华监控中心联网解决方案
  19. java怎么做3d可视化图形
  20. Android开发之银联工作密钥,主密钥,传输密钥(加解密图文展示)

热门文章

  1. http 回应头的闷事
  2. POS-商户手续费-从生活剖析,通俗易懂
  3. Python并发机制的实现(一)——多进程
  4. Python入门:局部变量与全局变量1
  5. Django model 反向引用中的related_name
  6. React.js 小书 Lesson10 - 组件的 state 和 setState
  7. vue.js 源代码学习笔记 ----- instance inject
  8. TypeScript之基本数据类型
  9. 网管学习日记-STP
  10. WLAN通信基础——WLAN物理层通信技术