Go语言EventBus

这篇具有很好参考价值的文章主要介绍了Go语言EventBus。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Go语言EventBus

EventBus是GoLang的小型轻量级事件总线,具有异步兼容性。

类似于观察者模式和发布订阅模式。

GitHub地址:https://github.com/asaskevich/EventBus

官方文档:https://pkg.go.dev/github.com/asaskevich/EventBus

1、安装使用

1.1 安装

go get github.com/asaskevich/EventBus

1.2 使用

import (
	evbus "github.com/asaskevich/EventBus"
)

2、简单例子

package main

import (
	"fmt"
	"github.com/asaskevich/EventBus"
)

func calculator(a int, b int) {
	fmt.Printf("%d\n", a + b)
}

func main() {
	bus := EventBus.New();
	bus.Subscribe("main:calculator", calculator);
	bus.Publish("main:calculator", 20, 40);
	bus.Unsubscribe("main:calculator", calculator);
}
# 程序输出
60

进行封装:

package main

import (
	"fmt"
	"github.com/asaskevich/EventBus"
)

type Bus struct {
	EventBus EventBus.Bus
}

func calculator(a int, b int) {
	fmt.Printf("a + b = "+"%d\n", a+b)
}

// Subscribe
func (bus *Bus) Subscribe() {
	err := bus.EventBus.Subscribe("main:calculator", calculator)
	if err != nil {
		fmt.Printf("Subscribe Error!")
	}
}

// UnSubscribe
func (bus *Bus) UnSubscribe() {
	err := bus.EventBus.Unsubscribe("main:calculator", calculator)
	if err != nil {
		fmt.Printf("UnSubscribe Error!")
	}
}

// Publish
func (bus *Bus) Publish() {
	bus.EventBus.Publish("main:calculator", 33, 60)
}

func main() {
	eventBus := EventBus.New()
	bus := &Bus{EventBus: eventBus}
	// 订阅一个
	// Subscribe
	bus.Subscribe()
	// Publish
	bus.Publish()
	// UnSubscribe
	bus.UnSubscribe()
}
# 程序输出
a + b = 93

订阅多个:

package main

import (
	"fmt"
	"github.com/asaskevich/EventBus"
)

type Bus struct {
	EventBus EventBus.Bus
}

func calculator1(a int, b int) {
	fmt.Printf("a + b = "+"%d\n", a+b)
}

func calculator2(a int, b int) {
	fmt.Printf("a - b = "+"%d\n", a-b)
}

// Subscribe
func (bus *Bus) Subscribe() {
	err1 := bus.EventBus.Subscribe("main:calculator", calculator1)
	if err1 != nil {
		fmt.Printf("Subscribe Error!")
	}
	err2 := bus.EventBus.Subscribe("main:calculator", calculator2)
	if err2 != nil {
		fmt.Printf("Subscribe Error!")
	}
}

// UnSubscribe
func (bus *Bus) UnSubscribe() {
	err1 := bus.EventBus.Unsubscribe("main:calculator", calculator1)
	if err1 != nil {
		fmt.Printf("UnSubscribe Error!")
	}
	err2 := bus.EventBus.Unsubscribe("main:calculator", calculator2)
	if err2 != nil {
		fmt.Printf("UnSubscribe Error!")
	}
}

// Publish
func (bus *Bus) Publish() {
	bus.EventBus.Publish("main:calculator", 33, 60)
}

func main() {
	eventBus := EventBus.New()
	bus := &Bus{EventBus: eventBus}
	// 订阅多个
	// Subscribe
	bus.Subscribe()
	// Publish
	bus.Publish()
	// UnSubscribe
	bus.UnSubscribe()
}
# 程序输出
a + b = 93
a - b = -27

Subscribe 可以放在 init 函数中:

package main

import (
	"fmt"
	"github.com/asaskevich/EventBus"
)

type Bus struct {
	EventBus EventBus.Bus
}

var bus *Bus

func calculator1(a int, b int) {
	fmt.Printf("a + b = "+"%d\n", a+b)
}

func calculator2(a int, b int) {
	fmt.Printf("a - b = "+"%d\n", a-b)
}

// Subscribe
func (bus *Bus) Subscribe() {
	err1 := bus.EventBus.Subscribe("main:calculator", calculator1)
	if err1 != nil {
		fmt.Printf("Subscribe Error!")
	}
	err2 := bus.EventBus.Subscribe("main:calculator", calculator2)
	if err2 != nil {
		fmt.Printf("Subscribe Error!")
	}
}

// UnSubscribe
func (bus *Bus) UnSubscribe() {
	err1 := bus.EventBus.Unsubscribe("main:calculator", calculator1)
	if err1 != nil {
		fmt.Printf("UnSubscribe Error!")
	}
	err2 := bus.EventBus.Unsubscribe("main:calculator", calculator2)
	if err2 != nil {
		fmt.Printf("UnSubscribe Error!")
	}
}

// Publish
func (bus *Bus) Publish() {
	bus.EventBus.Publish("main:calculator", 33, 60)
}

func init(){
	eventBus := EventBus.New()
	bus = &Bus{EventBus: eventBus}
	// 订阅多个
	// Subscribe
	bus.Subscribe()
}

func main() {
	// Publish
	bus.Publish()
	// UnSubscribe
	bus.UnSubscribe()
}
# 程序输出
a + b = 93
a - b = -27

3、实现的方法

  • New()
  • Subscribe()
  • SubscribeOnce()
  • HasCallback()
  • Unsubscribe()
  • Publish()
  • SubscribeAsync()
  • SubscribeOnceAsync()
  • WaitAsync()

3.1 New()

New() 返回具有空处理程序的新EventBus。

bus := EventBus.New();

3.2 Subscribe()

Subscribe(topic string, fn interface{}) error

订阅主题,如果 fn 不是函数,则返回 error。

func Handler() { ... }
...
bus.Subscribe("topic:handler", Handler)

3.3 SubscribeOnce

SubscribeOnce(topic string, fn interface{}) error

订阅一个主题一次,执行后将删除处理程序。如果fn不是函数,则返回error。

func HelloWorld() { ... }
...
bus.SubscribeOnce("topic:handler", HelloWorld)

3.4 Unsubscribe

Unsubscribe(topic string, fn interface{}) error

删除为主题定义的回调,如果没有订阅主题的回调,则返回错误。

bus.Unsubscribe("topic:handler", HelloWord);

3.5 HasCallback

HasCallback(topic string) bool

如果存在订阅该主题的任何回调,则返回true。

bus.HasCallback("topic:handler")

3.6 Publish

Publish(topic string, args ...interface{})

发布执行为主题定义的回调,任何额外的参数都将被传输到回调。

func Handler(str string) { ... }
...
bus.Subscribe("topic:handler", Handler)
...
bus.Publish("topic:handler", "Hello, World!");

3.7 SubscribeAsync

SubscribeAsync(topic string, fn interface{}, transactional bool)

订阅具有异步回调的主题,如果fn不是函数,则返回error。

func slowCalculator(a, b int) {
	time.Sleep(3 * time.Second)
	fmt.Printf("%d\n", a + b)
}

bus := EventBus.New()
bus.SubscribeAsync("main:slow_calculator", slowCalculator, false)

bus.Publish("main:slow_calculator", 20, 60)

fmt.Println("start: do some stuff while waiting for a result")
fmt.Println("end: do some stuff while waiting for a result")

bus.WaitAsync() // wait for all async callbacks to complete

fmt.Println("do some stuff after waiting for result")

transactional 参数确定主题的后续回调是串行运行(true)还是并发运行(false)。

3.8 SubscribeOnceAsync

SubscribeOnceAsync(topic string, args ...interface{})

SubscribeOnceAsync的工作方式与SubscribeOnce类似,只是异步执行回调。

3.9 WaitAsync()

WaitAsync等待所有异步回调完成。

4、跨流程事件

可与两个rpc服务配合使用:文章来源地址https://www.toymoban.com/news/detail-501603.html

  • 从服务器侦听远程发布的事件的客户端服务
  • 用于侦听客户端订阅的服务器服务

4.1 server

func main() {
    server := NewServer(":2010", "/_server_bus_", New())
    server.Start()
    // ...
    server.EventBus().Publish("main:calculator", 4, 6)
    // ...
    server.Stop()
}

4.2 client

func main() {
    client := NewClient(":2015", "/_client_bus_", New())
    client.Start()
    client.Subscribe("main:calculator", calculator, ":2010", "/_server_bus_")
    // ...
    client.Stop()
}

到了这里,关于Go语言EventBus的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • golang一个轻量级基于内存的kv存储或缓存

    golang一个轻量级基于内存的kv存储或缓存 go-cache是一个轻量级的基于内存的key:value 储存组件,类似于memcached,适用于在单机上运行的应用程序。 它的主要优点是,本质上是一个具有过期时间的线程安全map[string]interface{}。interface的结构决定了它不需要序列化。基于内存的特性

    2024年02月02日
    浏览(51)
  • 用go设计开发一个自己的轻量级登录库/框架吧

    几乎每个项目都会有登录,退出等用户功能,而登录又不单仅仅是登录,我们要考虑很多东西。 token该怎么生成?生成什么样的? 是在Cookie存token还是请求头存token?读取的时候怎么读取? 允许同一个账号被多次登录吗?多次登录他们的token是一样的?还是不一样的? 登录也

    2024年02月03日
    浏览(40)
  • 用go设计开发一个自己的轻量级登录库/框架吧(业务篇)

    本篇会讲讲框架的登录业务的实现。实现三种登录模式: 同一用户只能登录一次 同一用户多次登录多token 同一用户多次登录共享一个token 源码:weloe/token-go: a light login library (github.com) 首先从我们要考虑是底层该怎么存储登录信息来去达成这三种登录模式 同一用户只能登录一

    2024年02月04日
    浏览(42)
  • 用go设计开发一个自己的轻量级登录库/框架吧(拓展篇)

    主库:weloe/token-go: a light login library. 扩展库:weloe/token-go-extensions (github.com) 本篇给主库扩展一个Adapter提供简单的外部数据存储。 一个库/框架往往不能完成所有事情,需要其他库/框架的支持才能达到更加完善的效果。本篇会对token-go框架的Adapter进行简单的拓展。 首先我们应

    2024年02月05日
    浏览(59)
  • 用go设计开发一个自己的轻量级登录库/框架吧(项目维护篇)

    本篇将开始讲讲开发库/框架的最开始阶段,也就是搭建一个项目 源码:weloe/token-go: a light login library (github.com) 项目结构,不是上一篇所说的代码架构,而是分包,明确的分包更有助于我们的开发。本框架分包如下 我们选择使用GitHub进行代码托管,同时也使用GitHub Actions进行

    2024年02月03日
    浏览(39)
  • Lua: 一门轻量级、高效的脚本语言

    在当今软件开发的领域中,寻找一门既灵活又高效的脚本语言,一直是开发者们追求的目标。Lua作为一门小巧、高效、可嵌入的脚本语言,已经成为了众多开发者的首选之一。无论是游戏开发、嵌入式系统、Web 开发还是其他领域,Lua 都展现出了其强大的应用价值和广泛的适

    2024年02月20日
    浏览(31)
  • 【嵌入式开源库:cJSON】 一个轻量级C语言JSON数据解析库用法详解

    cJSON是使用C语言编写,用来创建、解析JSON文件的库。cJSON特点就是工程文件简单,只有 一个.c 和 一个.h ,但提供函数接口功能齐全,麻雀虽小五脏俱全,使得在嵌入式工程中使用起来得心应手。 https://github.com/DaveGamble/cJSON 只需拉取 cJSON.c 和 cJSON.h 即可。 给出如下JSON格式示

    2023年04月26日
    浏览(79)
  • 轻量级c语言开源日志库log.c介绍 - 实现不同级别和参数化日志打印

    c语言没有现成的日志库,如果要记录日志,需要自己封装一个日志库。如果要实现日志级别和参数打印,还是比较麻烦的,正好在github找到了一个c语言开源日志库,可以实现日志级别打印,参数打印,而且还会记录日期和行号,最重要的是代码非常少,只有100多行,可以直

    2024年02月07日
    浏览(40)
  • git轻量级服务器gogs、gitea,非轻量级gitbucket

    本文来源:git轻量级服务器gogs、gitea,非轻量级gitbucket, 或 gitcode/gogs,gitea.md 结论: gogs、gitea很相似 确实轻, gitbucket基于java 不轻, 这三者都不支持组织树(嵌套组织 nested group) 只能一层组织。 个人用,基于gogs、gitea,两层结构树 简易办法: 把用户当成第一层节点、该用户的

    2024年02月07日
    浏览(54)
  • 轻量灵动: 革新轻量级服务开发

    从 JDK 8 升级到 JDK 17 可以让你的应用程序受益于新的功能、性能改进和安全增强。下面是一些 JDK 8 升级到 JDK 17 的最佳实战: 1.1、确定升级的必要性:首先,你需要评估你的应用程序是否需要升级到 JDK 17。查看 JDK 17 的新特性、改进和修复的 bug,以确定它们对你的应用程序

    2024年02月07日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包