构建一个即时消息应用(五):实时消息

构建一个即时消息应用(五):实时消息-1

本文是该系列的第五篇。

  • 第一篇: 模式
  • 第二篇: OAuth
  • 第三篇: 对话
  • 第四篇: 消息

对于实时消息,我们将使用 服务器发送事件 Server-Sent Events 。这是一个打开的连接,我们可以在其中传输数据流。我们会有个端点,用户会在其中订阅发送给他的所有消息。

消息户端

在 HTTP 部分之前,让我们先编写一个 映射 map ,让所有客户端都监听消息。 像这样全局初始化:

type MessageClient struct {
    Messages chan Message
    UserID   string
}

var messageClients sync.Map

已创建的新消息

还记得在 上一篇文章 中,当我们创建这条消息时,我们留下了一个 “TODO” 注释。在那里,我们将使用这个函数来调度一个 goroutine。

go messageCreated(message)

把这行代码插入到我们留注释的位置。

func messageCreated(message Message) error {
    if err := db.QueryRow(`
 SELECT user\_id FROM participants
 WHERE user\_id != $1 and conversation\_id = $2
 `, message.UserID, message.ConversationID).
    Scan(&message.ReceiverID); err != nil {
        return err
    }

    go broadcastMessage(message)

    return nil
}

func broadcastMessage(message Message) {
    messageClients.Range(func(key, \_ interface{}) bool {
        client := key.(\*MessageClient)
        if client.UserID == message.ReceiverID {
            client.Messages