Go 语言实现 WebSocket 推送

本文介绍了如何在分布式系统中使用Go语言和WebSocket实现消息推送。通过结合redis作为协同中间件,存储用户连接信息,当消息实例生成消息时,通过redis获取连接信息并推送到对应终端。文章详细阐述了Client、ClientManager组件的设计以及消息推送的流程。
摘要由CSDN通过智能技术生成

作者:周慧婷

写在前面

系统开发的过程中,我们经常需要实现消息推送的需求。单端单实例的情况下很好处理(网上有许多教程这里不做展开),但在分布式系统及多端需要推送的情况下该如何处理呢?

在分布式系统中,消息推送服务端是多实例的。某系统中一个服务生成一条消息,这条消息需要实时推送到多个终端,此时该如何进行有效的 WebSocket 推送呢?首先一起看看如下场景:

假设推送消息由消息实例 2 产生,但是终端真正连接的消息实例是实例 1 和实例 3,并没有连接到生产消息的实例 2,系统是如何将实例 2 的消息同步推送到终端 1 和终端 2 的呢?下文将详细描述。

file

基本原理

为了满足需求我们采用 redis 做协同中间件,用于存储用户信息、生成用户连接的唯一性标识以及 pod address,消息的生产者实例通过订阅 redis 获取终端连接的唯一性标识和 pod address,并通知到对应的消息实例,最终由相应连接终端的消息实例通过 WebSocket 将消息发推送到用户终端。具体流程如下图:

file

服务端实现

Client

Client 组件的作用,是当用户与消息服务中某个实例建立连接后,管理这个连接的信息,这里通过一个 Golang 结构体来定义:

type Client struct {
   
    UUID   string 
    UserID string
    Socket *websocket.Conn
    Send   chan []byte
}

结构体中的数据类型说明如下:

  • UUID:对连接进行唯一性的标识,通过此标识可以查找到连接信息。
  • UserID:用户 ID。
  • Socket:连接对象。
  • Send:消息数据 channel。

我们为 Client 结构体实现了两个方法:Read、Write 来处理消息的接受和发送。

Read 方法

Read 方法比较简单,从终端接收请求消息后,消息实例通过 WebSocket 回应接收消息状态,并不返回请求结果。结果通过 Write 方法返回。

func (c *Client) Read(close, renewal chan *Client) {
   
    defer func() {
   
        close <- c
    }()

for {
   
    _, message, err := c.Socket.ReadMessage(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值