面UCloud的时候问到了这题,下来看了一下是基于观察者模式实现的,仅作记录

/**
* @Author: lzw5399
* @Date: 2021/5/20 20:38
* @Desc: 基于观察者模式实现的订阅发布
*/
package main import (
"errors"
"fmt"
"sync"
) func main() {
server := NewServer()
server.Subscribe("CCTV1", NewBasicClient("张三"))
server.Subscribe("CCTV2", NewBasicClient("张三"))
server.Subscribe("CCTV1", NewBasicClient("李四")) server.Publish("CCTV1", "开播辣!")
} // ---server---
type Server struct {
Topics map[string]*Topic // k=topicName v=topic
sync.RWMutex
} func NewServer() *Server {
return &Server{
Topics: make(map[string]*Topic),
RWMutex: sync.RWMutex{},
}
} func (s *Server) Subscribe(topicName string, client Client) {
s.RLock()
topic, exist := s.Topics[topicName]
s.RUnlock() // 存在topic直接添加client
if exist {
topic.AddClient(client)
return
} // 不存在topic,新建topic,在添加client
topic = NewTopic(topicName)
topic.AddClient(client)
s.Lock()
s.Topics[topicName] = topic
s.Unlock()
} func (s *Server) Publish(topicName string, message string) error {
s.RLock()
topic, exist := s.Topics[topicName]
s.RUnlock() if exist {
topic.Notify(message)
return nil
} return errors.New("当前topic不存在")
} // ---end server--- // ---topic---
type Topic struct {
Name string
clients map[string]Client // k=clientName v=client
sync.RWMutex
} func NewTopic(name string) *Topic {
return &Topic{
Name: name,
clients: make(map[string]Client),
RWMutex: sync.RWMutex{},
}
} func (t *Topic) AddClient(client Client) {
// 只添加存在的
if _, exist := t.clients[client.Name()]; !exist {
t.Lock()
t.clients[client.Name()] = client
t.Unlock()
}
} func (t *Topic) Notify(message string) {
for _, v := range t.clients {
v.ConsumeCallback(message)
}
} // ---end topic--- // ---client---
type Client interface {
Name() string
ConsumeCallback(message string)
} type BasicClient struct {
name string
} func NewBasicClient(name string) *BasicClient {
return &BasicClient{
name: name,
}
} func (b *BasicClient) Name() string {
return b.name
} func (b *BasicClient) ConsumeCallback(message string) {
fmt.Printf("当前Client: %s, 接收到的消息为: %s\n", b.Name(), message)
} // ---end client---

Go基于观察者模式实现的订阅/发布的更多相关文章

  1. 基于Redis消息的订阅发布应用场景

    目录 基于Redis消息的订阅发布应用场景 1.应用背景 2.困境 2.1 锁表风险 2.2 实时性差 2.3 增加编程复杂性 2.4 实时效果 3.解决方案 3.1 前端传值给服务端 3.2 服务端 ...

  2. 基于Redis的消息订阅/发布

    在工业生产设计中,我们往往需要实现一个基于消息订阅的模式,用来对非定时的的消息进行监听订阅. 这种设计模式在 总线设计模式中得到体现.微软以前的WCF中实现了服务总线 ServiceBus的设计模式. ...

  3. 通过Dapr实现一个简单的基于.net的微服务电商系统(四)——一步一步教你如何撸Dapr之订阅发布

    之前的章节我们介绍了如何通过dapr发起一个服务调用,相信看过前几章的小伙伴已经对dapr有一个基本的了解了,今天我们来聊一聊dapr的另外一个功能--订阅发布 目录:一.通过Dapr实现一个简单的基 ...

  4. 分布式消息总线,基于.NET Socket Tcp的发布-订阅框架之离线支持,附代码下载

    一.分布式消息总线以及基于Socket的实现 在前面的分享一个分布式消息总线,基于.NET Socket Tcp的发布-订阅框架,附代码下载一文之中给大家分享和介绍了一个极其简单也非常容易上的基于.N ...

  5. 基于.NET Socket Tcp的发布-订阅框架

    基于.NET Socket Tcp的发布-订阅框架 一.分布式消息总线 在很多MIS项目之中都有这样的需求,需要一个及时.高效的的通知机制,即比如当使用者A完成了任务X,就需要立即告知使用者B任务X已 ...

  6. 基于Http协议订阅发布系统设计

      基于Http协议订阅发布系统设计 --物联网系统架构设计   1,订阅发布(subscriber-publisher)      订阅发布模式最典型的应用场景就是消息系统的设计.在消息系统的架构中 ...

  7. Java里观察者模式(订阅发布模式)

    创建主题(Subject)接口 创建订阅者(Observer)接口 实现主题 实现观察者 测试 总结 在公司开发项目,如果碰到一些在特定条件下触发某些逻辑操作的功能的实现基本上都是用的定时器 比如用户 ...

  8. 基于redis的消息订阅与发布

    Redis 的 SUBSCRIBE 命令可以让客户端订阅任意数量的频道, 每当有新信息发送到被订阅的频道时, 信息就会被发送给所有订阅指定频道的客户端. 作为例子, 下图展示了频道 channel1  ...

  9. 基于观察者模式-----otto源码分析

    一.otto简介 otto是支付公司square一个专注于android的开源项目,该项目是一个event bus模式的消息框架,是一个基于Guava的增强型事件总线.旨在将应用程序的不同部分分离,同 ...

  10. ASP.NET MVC 学习笔记-2.Razor语法 ASP.NET MVC 学习笔记-1.ASP.NET MVC 基础 反射的具体应用 策略模式的具体应用 责任链模式的具体应用 ServiceStack.Redis订阅发布服务的调用 C#读取XML文件的基类实现

    ASP.NET MVC 学习笔记-2.Razor语法   1.         表达式 表达式必须跟在“@”符号之后, 2.         代码块 代码块必须位于“@{}”中,并且每行代码必须以“: ...

随机推荐

  1. 7 个非常实用的 Shell 拿来就用脚本实例!

    前天,在群里看到有一位读者分享了几道 Shell 脚本实例题目,索性看到了,不如来写写巩固下基础知识,如下: 1. 并发从数台机器中获取 hostname,并记录返回信息花费的时长,重定向到一个文件 ...

  2. Octave 安装教程

    Octave 用心写著. Octave为GNU项目下的开源软件.同时它也是一种语言,专注于解决线性计算问题.因为对于矩阵计算的优化,使得其速度远高于循环计算.语法兼容Linux shell. Octa ...

  3. 如何在Spark键值对数据中,对指定的Key进行输出/筛选/模式匹配

    在用键值对RDD进行操作时,经常会遇到不知道如何筛选出想要数据的情况,这里提供了一些解决方法 目录 1.对固定的Key数据进行查询 2.对不固定的Key数据进行模糊查询 1.对固定的Key数据进行查询 ...

  4. NOIP2024模拟赛10:热烈张扬

    NOIP2024模拟赛10:热烈张扬 T1 一句话题意:给定一颗树和两个玩家的起点 \(a,b\) 和各自的移动速度 \(da,db\).问:如果二人均以最优策略移动,问最后谁是赢家(先走到对方当前位 ...

  5. 30k的测试简历长这样,进来抄作业!

    面试求职: 「面试试题小程序」,内容涵盖 测试基础.Linux操作系统.MySQL数据库.Web功能测试.接口测试.APPium移动端测试.Python知识.Selenium自动化测试相关.性能测试. ...

  6. pjsip编译、说明及vs2022使用示例

    环境: window10_x64 & vs2022 pjsip版本: 2.14.1   之前整理过pjsip 2.10的编译及python使用示例: https://www.cnblogs.c ...

  7. 周末基于 .NET 9 + K8S 写了个 MockHttp

    MockHTTP MockHTTP 可以将现有HTTP转换成GET请求,设置cron定时调用,自定义代码去格式化数据,通知到你的邮箱里. 比如每天早上时自动获取博客园文章列表,天气下雨时通知,各类签到 ...

  8. Java ScheduledThreadPoolExecutor延迟或周期性执行任务

    ImportNew注: 本文由新浪微博:@小飞侠_thor投稿至ImportNew.感谢@小飞侠_thor ! 如果你希望分享好的原创文章或者译文,欢迎投稿到ImportNew. Java提供的Tim ...

  9. java动态跟踪分析工具BTrace实现原理

    今天,Team Leader推荐了一个非常棒的动态跟踪分析工具 – BTrace.由于对它的实现原理非常感兴趣,于是花了点时间研究了一下,顺便写点心得. 什么是BTrace? BTrace是SUN K ...

  10. 进程管理工具之PM2

    Github地址 https://github.com/Unitech/pm2 官方文档 http://pm2.keymetrics.io/docs/usage/quick-start/ npm安装 ...