Go基于观察者模式实现的订阅/发布
面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基于观察者模式实现的订阅/发布的更多相关文章
- 基于Redis消息的订阅发布应用场景
目录 基于Redis消息的订阅发布应用场景 1.应用背景 2.困境 2.1 锁表风险 2.2 实时性差 2.3 增加编程复杂性 2.4 实时效果 3.解决方案 3.1 前端传值给服务端 3.2 服务端 ...
- 基于Redis的消息订阅/发布
在工业生产设计中,我们往往需要实现一个基于消息订阅的模式,用来对非定时的的消息进行监听订阅. 这种设计模式在 总线设计模式中得到体现.微软以前的WCF中实现了服务总线 ServiceBus的设计模式. ...
- 通过Dapr实现一个简单的基于.net的微服务电商系统(四)——一步一步教你如何撸Dapr之订阅发布
之前的章节我们介绍了如何通过dapr发起一个服务调用,相信看过前几章的小伙伴已经对dapr有一个基本的了解了,今天我们来聊一聊dapr的另外一个功能--订阅发布 目录:一.通过Dapr实现一个简单的基 ...
- 分布式消息总线,基于.NET Socket Tcp的发布-订阅框架之离线支持,附代码下载
一.分布式消息总线以及基于Socket的实现 在前面的分享一个分布式消息总线,基于.NET Socket Tcp的发布-订阅框架,附代码下载一文之中给大家分享和介绍了一个极其简单也非常容易上的基于.N ...
- 基于.NET Socket Tcp的发布-订阅框架
基于.NET Socket Tcp的发布-订阅框架 一.分布式消息总线 在很多MIS项目之中都有这样的需求,需要一个及时.高效的的通知机制,即比如当使用者A完成了任务X,就需要立即告知使用者B任务X已 ...
- 基于Http协议订阅发布系统设计
基于Http协议订阅发布系统设计 --物联网系统架构设计 1,订阅发布(subscriber-publisher) 订阅发布模式最典型的应用场景就是消息系统的设计.在消息系统的架构中 ...
- Java里观察者模式(订阅发布模式)
创建主题(Subject)接口 创建订阅者(Observer)接口 实现主题 实现观察者 测试 总结 在公司开发项目,如果碰到一些在特定条件下触发某些逻辑操作的功能的实现基本上都是用的定时器 比如用户 ...
- 基于redis的消息订阅与发布
Redis 的 SUBSCRIBE 命令可以让客户端订阅任意数量的频道, 每当有新信息发送到被订阅的频道时, 信息就会被发送给所有订阅指定频道的客户端. 作为例子, 下图展示了频道 channel1 ...
- 基于观察者模式-----otto源码分析
一.otto简介 otto是支付公司square一个专注于android的开源项目,该项目是一个event bus模式的消息框架,是一个基于Guava的增强型事件总线.旨在将应用程序的不同部分分离,同 ...
- ASP.NET MVC 学习笔记-2.Razor语法 ASP.NET MVC 学习笔记-1.ASP.NET MVC 基础 反射的具体应用 策略模式的具体应用 责任链模式的具体应用 ServiceStack.Redis订阅发布服务的调用 C#读取XML文件的基类实现
ASP.NET MVC 学习笔记-2.Razor语法 1. 表达式 表达式必须跟在“@”符号之后, 2. 代码块 代码块必须位于“@{}”中,并且每行代码必须以“: ...
随机推荐
- HEU KMS:一款超稳的MS Windows激活工具
HEU KMS ACTIVATOR是一款功能齐全的免费Windows和Office系列激活工具. 打开程序,一步到位.直接点击开始就可以准备激活,Windows11/10乃至更早的版本都可以通用,顺带 ...
- C++新版本特性
C++新特性 1.C++11 中的新特性 C++11 引入了许多新特性,包括自动类型推导.lambda 表达式.右值引用等.下面介绍其中的一些重要特性. 1.1 自动类型推导(Type Inferen ...
- Web渗透06_XSS
XSS漏洞描述 XSS是非常厉害的漏洞,在OWASP TOP10中榜上有名. XSS攻击通常指的是通过利用网页开发时留下的漏洞,通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网 ...
- SSIS ODBC方式连接mysql数据库
系统环境:WIN 10 64位 1.安装Mysql odbc connector 插件 文章说明链接: https://www.cnblogs.com/santiagoMunez/p/4780301. ...
- OpenFeign简单使用
OpenFeign入门 什么是 OpenFeign? OpenFeign是一个远程访问的组件,用于两个微服务之间互相访问的中间件 OpenFeign使用步骤 1.添加OpenFeign的依赖 < ...
- js实现浏览器后退页面刷新
最近在开发中遇到一个问题: 在一个列表页面,点击进入详情,详情页面对其状态操作,其详情页面有做修改,然后点击浏览器后退,返回到列表页,在列表页面状态还是操作之前的,为解决状态统一需要手动刷新改列表页. ...
- python报错:If this call came from a _pb2.py file, your generated code is out of date and must be regenerated with protoc >= 3.19.0
相关: https://stackoverflow.com/questions/72441758/typeerror-descriptors-cannot-not-be-created-directl ...
- LeetCode128 最长连续序列
最长连续序列 题目链接:LeetCode128 描述 给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度. 请你设计并实现时间复杂度为 O(n) 的算法 ...
- 基于Java+SpringBoot+Mysql实现的快递柜寄取快递系统功能实现六
一.前言介绍: 1.1 项目摘要 随着电子商务的迅猛发展和城市化进程的加快,快递业务量呈现出爆炸式增长的趋势.传统的快递寄取方式,如人工配送和定点领取,已经无法满足现代社会的快速.便捷需求.这些问题不 ...
- VMware安装教程---------------------以及Windows,Linux,Apple MAC OS系统安装
1.什么是VMware虚拟机 VMware虚拟机是一个虚拟机软件,它可以在一台机器上同时运行多个系统,这些系统包括Windows,Linux,Apple os等. 2.虚拟机有什么用 虚拟机的用处很多 ...