使用 SSE(Server-Sent Events) 进行 HTTP 服务器推送

这个示例是一个类似 twitter 的 web 应用程序,使用 Server-Sent Events 来支持实时刷新。

运行

docker-compose up

然后, 浏览 http://localhost:8080

您可以添加自己的帖子或点击按钮获得随机生成的帖子。

无论哪种方式,feeds 列表和 feed 中的帖子都应该是最新的。尝试使用第二个浏览器窗口查看更新。

它是如何工作的

  • 可以创建和更新帖子。

  • 帖子可以包含标签。

  • 每个标签都有自己的 feed,其中包含来自该标签的所有帖子。

  • 所有的帖子都存储在 MySQL 中。这就是写模型。

  • 所有 feed 都异步更新并存储在 MongoDB 中。这是读模型。

为什么要使用单独的写和读模型?

对于这个示例应用程序,使用多语言持久性(两个数据库引擎)当然有些过头了。我们这样做是为了展示这个技术,以及如何很容易地将它应用到 Watermill。

专用的读模型对于具有高读/写比率的应用程序是一种有用的模式。所有写操作都被原子地应用到写模型(在我们的例子中是 MySQL)。事件处理程序异步更新读模型(我们使用 Mongo)。

读取模型中的数据可以按原样使用。也可以独立于写模型进行扩展。

请记住,要使用此模式,应用程序中必须接受最终的一致性。而且,在大多数用例中,您可能不需要使用它。务实!

SSE Router

SSERouter 来自 watermill-http。当创建一个新的路由器时,你需要传递一个上游订阅者。来自该订阅服务器的消息将触发通过 HTTP 推送更新。

在本例中,我们使用 NATS 作为 Pub/Sub,但这可以是 Watermill 支持的任何 Pub/Sub。

sseRouter, err := watermillHTTP.NewSSERouter(    watermillHTTP.SSERouterConfig{        UpstreamSubscriber: router.Subscriber,        ErrorHandler:       watermillHTTP.DefaultErrorHandler,    },    router.Logger,)

Stream Adapters(流适配器)

要使用 SSERouter,你需要准备一个带有两个方法的 StreamAdapter

GetResponse 类似于标准的 HTTP 处理程序。修改现有的处理程序来匹配这个签名应该非常容易。

Validate 是一个额外的方法,它告诉我们是否应该为特定的 Message 推送更新。

type StreamAdapter interface {// GetResponse returns the response to be sent back to client.// Any errors that occur should be handled and written to `w`, returning false as `ok`.   GetResponse(w http.ResponseWriter, r *http.Request) (response interface{}, ok bool)// Validate validates if the incoming message should be handled by this handler.// Typically this involves checking some kind of model ID. Validate(r *http.Request, msg *message.Message) (ok bool)}

Validate 示例如下所示。它检查消息是否来自与用户通过 HTTP 请求发送的相同的 post ID。

func (p postStreamAdapter) Validate(r *http.Request, msg *message.Message) (ok bool) { postUpdated := PostUpdated{}

   err := json.Unmarshal(msg.Payload, &postUpdated)if err != nil {return false }

   postID := chi.URLParam(r, "id")

return postUpdated.OriginalPost.ID == postID}

如果你想为每条消息触发一个更新,你可以简单地返回 true

func (f allFeedsStreamAdapter) Validate(r *http.Request, msg *message.Message) (ok bool) {return true}

在开始 SSERouter 之前,您需要添加带有特定主题的处理程序。 AddHandler 返回一个可以在任何路由库中使用的标准 HTTP 处理程序。

postHandler := sseRouter.AddHandler(PostUpdatedTopic, postStream)

// ...

r.Get("/posts/{id}", postHandler)

Event handlers(事件处理程序)

该示例使用 Watermill 进行所有异步通信,包括 SSE。

发布了以下事件:

  • PostCreated

    • 将 post 添加到贴子中包含标签的所有 feeds 中。

  • FeedUpdated

    • 将更新推送到当前访问 feed 页面的所有客户端。

  • PostUpdated

    • a) 对于现有标签,帖子内容将在标签中更新。

    • b) 如果添加了新的标签,文章将被添加到标签的 feed 中。

    • c) 如果标签已删除,则该帖子将从标签的 feed 中删除。

    • 将更新推送给所有当前访问 post 页面的客户端。

    • 使用帖子中存在的标签更新所有 feeds 中的帖子

前端 app

前端应用程序是使用 Vue.js 和 Bootstrap 构建的。

最有趣的部分是 EventSource 的使用。

this.es = new EventSource('/api/feeds/' + this.feed)

this.es.addEventListener('data', event => {let data = JSON.parse(event.data);this.posts_stream = data.posts;}, false);

Refs

  • watermill.io

服务器推送_初探 Watermill 构建 Golang 事件驱动程序,SSE 进行 HTTP 服务器推送相关推荐

  1. sam服务器是什么_使用SAM CLI将机器学习模型部署到无服务器后端

    sam服务器是什么 介绍 (Introduction) Over the last year at CMRA, we have been incorporating more machine lear ...

  2. 伤害世界服务器连接失败_伤害世界Hurtworld怎么开服 伤害世界Hurtworld服务器开服方法...

    伤害世界Hurtworld是一款自由相当高的生存射击网游戏,很多朋友想和自己的小伙伴们一起对抗邪恶的入侵者,但这里就必须得开个服务器才能做到,东坡小编特意带来了伤害世界Hurtworld服务器开服图文 ...

  3. 批量关闭公众号推送_微信内测新功能:可批量关闭订阅号推送

    据腾讯科技报道,微信近期正在内测一项新功能,以提醒部分微信用户,关注列表中存在一些很久都没有阅读过的订阅号.通过这条提醒,用户可以一键选择不接受这些订阅号的推送.据微信官方透露,目前只有部分 iOS ...

  4. python内推群_重要!!!陌陌2020校招Python内推通道(含内推直链)

    陌陌校招正式开启,今天给大家来一份陌陌2020的校招内推. 本次陌陌内推的对象为 2020 届毕业的全日制本科.硕士.博士在校生,有意向去陌陌的各位可以努力一把了. 内推简历通过简历筛选后免笔试,直接 ...

  5. 斗战神服务器正在维护6,斗战神什么时候服务器数据互通_斗战神1月6日、8日服务器数据互通公告_快吧游戏...

    亲爱的斗粉: 狮驼城现已开启,天王堡全新团队副本静待众英雄前来挑战.了更好的聚集战斗力,方便大家挑战全新团队副本,我们将于1月6日9点起,对御马监.昆仑山.女国宫三组服务器,进行停机维护,预计将持续5 ...

  6. twitter无法获取推文_某些第三方Twitter客户端可能无法发送更长的推文

    最后,您现在可以发布的推文是以前的两倍.正如Twitter 周二宣布的那样,它于2017年9月作为测试引入的新的280个字符限制已被推向服务的所有用户和所有语言.9月,我们启动了一项测试,该测试扩展了 ...

  7. javascript程序_使用JavaScript构建实时应用程序的5种方法

    javascript程序 There was a point in time where we didn't expect too much from web pages. Which reminds ...

  8. swift通知栏推送_如何使用Swift和Laravel使用推送通知创建iOS加密跟踪应用

    swift通知栏推送 by Neo Ighodaro 由新Ighodaro 如何使用Swift和Laravel使用推送通知创建iOS加密跟踪应用 (How to create an iOS crypt ...

  9. 如何构建一套高可用的 APP 消息推送平台

    转载自  如何构建一套高可用的 APP 消息推送平台 消息推送作为移动 APP 运营中的一项关键技术,已经被越来越广泛的运用.本文追溯了推送技术的发展历史,剖析了其核心原理,并对推送服务的关键技术进行 ...

最新文章

  1. 护壁桩嵌入深度_泥浆护壁成孔灌注桩施工时泥浆的作用有哪些?
  2. Facebook狂撒20万美元,悬赏用AI检测P图盗版问题
  3. debug assertion failed!报错
  4. java遍历集合选择题_Java集合知识测试B
  5. Wireshark软件的安装,进行数据包的捕获【Wireshark安装使用】
  6. matlab cep,【CEP】重构和改进HelloInsightObservable
  7. c语言时钟报告,C语言图形时钟课程设计实验报告
  8. python程序代码解析_Python源码分析3 – 词法分析器PyTokenizer
  9. PHPCMS 模板的设置
  10. 【Python开发】Python中的class继承
  11. python 代码行数统计工具_使用Python设计一个代码统计工具
  12. xshell、xftp官方免费版下载
  13. 21天自学c语言漫画版,21天学通C语言第6版
  14. Adobe pr,ae,ps...软件的安装,及简单的使用
  15. vue两列数据 合并成一列
  16. 东电计算机专业好就业吗,东北电力大学就业前景怎样好不好
  17. BottomNavigationView与Navigation使用
  18. 猴子搬香蕉(算法入门题目005)
  19. 全球及中国玄武岩纤维市场竞争格局分析及发展前景预测报告2022-2028年版
  20. 2017711010137 赵栋 《面向对象程序设计》第四章学习总结

热门文章

  1. html5 vr效果,HTML5 Three.js 虚拟现实小实验(VR Experiment)
  2. element 方法返回的boolean被当成字符串了_JavaScript 原生对象、属性、方法、事件、事件参数...
  3. kvmweb管理工具_KVM的web管理界面
  4. 我的工作网怎么样_分享一下我在珍爱网的相亲经历
  5. xp正版验证补丁_实操web漏洞验证——IIS HTTP.sys 整数溢出漏洞
  6. linux 创建用户和修改新增用户默认的家目录
  7. 第七篇:Spring Boot整合Thymeleaf_入门试炼02
  8. linux搭建SonarQube_Oracle
  9. hilbert谱 matlab,怎么在matlab中做信号hilbert边际谱分析
  10. qt使用动画提示正在载中