面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. OpenFunction v0.8.0 发布:通过 Dapr Proxy 加速函数启动

    相较于其他函数计算项目,OpenFunction 有很多独特的功能,其中之一便是通过 Dapr 与各种后端服务(BaaS)无缝集成.目前 OpenFunction 已经支持了 Dapr 的 pub/s ...

  2. 题解:AT_abc370_c [ABC370C] Word Ladder

    题目传送门 luogu观看 简要题意 给两个序列 \(S\) 和 \(T\),输出的第一个数是它能改变的总个数,后面跟着的第 \(i\) 个是改变 \(i\) 个数之后,字典序最小的结果. 思路 当 ...

  3. 强化学习算法笔记之【DDPG算法】

    强化学习笔记之[DDPG算法] 目录 强化学习笔记之[DDPG算法] 前言: 原论文伪代码 DDPG 中的四个网络 代码核心更新公式 前言: 本文为强化学习笔记第二篇,第一篇讲的是Q-learning ...

  4. 鱼香ROS一键安装软件

    一行代码-解决人生烦恼 推荐语:一行代码搭建机器人开发环境(ROS/ROS2/ROSDEP) 开源地址:https://github.com/fishros/install 一键安装指令 wget h ...

  5. buck电路 & boost电路

    buck电路 buck电路是直流的降压电路,我们下面给大家讲下,如何把12V的直流电压降压成5V的直流电压 1.buck电路拓扑:12V----->5V 2.降压原理 a.开关闭合,电流走向 电 ...

  6. 2024/9/16 CSP-S模拟赛试题

    A 这题是很有意思的一个题,思路就是你考虑kt的位置只可能在四个角,因为这种情况下,他的距离才会最远对吧,所以你就暴力找另一个人fengwu的点的位置,然后计算他们之间的距离然后你求一个\(\max\ ...

  7. 如果一个接口不使用token鉴权,应该怎么保持在登录状态下进行测试?

    1.token是接口中用于身份验证和授权的令牌,用户通过登录操作,服务器会返回一个token,这个token会在后续的请求中发送到服务器,用来证明用户的身份和权限. 2.如果接口没有token,可以使 ...

  8. 货店管理(delphi+sqlserver)

    之前给朋友做的货店管理程序,个人使用,数据量小,delphi开发的,sqlserver express版,fastReport做的报表(报表可以修改). 源代码全给他的,呵呵,他也可以简单修改了.   ...

  9. Polly+HttpClientFactory

    Polly 在.Net Core中有一个被.Net基金会认可的库Polly,它一种弹性和瞬态故障处理库,可以用来简化对服务熔断降级的处理. Polly的策略主要由"故障"和&quo ...

  10. 前端截图取色工具Snipaste

    在Web前端开发中,在写页面CSS样式时经常要用工具去取色来设置字体颜色.背景颜色.边框颜色等等,以还原设计图的最佳效果.今天给大家推荐的取色工具是Snipaste.Snipaste 是一个简单但强大 ...