Go 實現在線用戶消息推送實戰!

前言

今天老闆又給下了一個需求,在線用戶的消息推送,這個功能我相信 95% 的產品都有這個需求,

比如下面的需求場景

1: 運營給在線的用戶推送一些活動或者文案或者公告

2: 實時監控和通知:在監控系統中,可以使用消息推送來實時向操作員發送系統警報和通知。例如,當系統出現異常或達到某個閾值時,服務器可以向操作員發送警報消息。

3: 社交網絡和新聞資訊:使用消息推送來通知用戶有新的消息、新的粉絲或者新的內容更新,增強用戶參與度和留存率。

等等 ... 太多了場景,所以這個技術點我們一定要掌握起原理,防止哪天此類需求落到我們頭上

Go+Html 實現消息推送

實現需求:運營端:Admin.html 用於模擬運營發送公告指令 用戶端:Client.html 用戶模擬用戶客戶端 服務端:Server.go 服務器

消息推送服務器 Server.go

package main

import (
 "fmt"
 "net/http"

 "github.com/gorilla/websocket"
)

var (
 clients   = make(map[*websocket.Conn]bool)
 broadcast = make(chan []byte)
 upgrader  = websocket.Upgrader{
  CheckOrigin: func(r *http.Request) bool {
   return true // 允許所有來源的連接
  },
 }
)

func handleMessages() {
 for {
  message := <-broadcast
  fmt.Println("broadcast Start")

  for client := range clients {
   fmt.Println(message)
   err := client.WriteMessage(websocket.TextMessage, message)
   if err != nil {
    fmt.Println("Error writing to client:", err)
    client.Close()
    delete(clients, client)
   }
  }
 }
}

func wsHandler(w http.ResponseWriter, r *http.Request) {
 conn, err := upgrader.Upgrade(w, r, nil)
 if err != nil {
  fmt.Println("Error upgrading to websocket:", err)
  return
 }
 defer conn.Close()

 clients[conn] = true

 for {
  _, by, err := conn.ReadMessage()
  if err != nil {
   fmt.Println("Client disconnected:", err)
   delete(clients, conn) // 從映射中移除客戶端
   break
  }
  // 將字節數據轉換爲字符串
  message := string(by)
  broadcast <- []byte(message)
 }
}

func main() {
 http.HandleFunc("/ws", wsHandler)
 go handleMessages()
 fmt.Println("Server running on localhost:8080")
 http.ListenAndServe(":8080", nil)
}

運營操作端 Admin.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta >
    <title>Admin Panel</title>
</head>
<body>
<input type="text" id="messageInput" placeholder="Type your message...">
<button onclick="sendMessage()">Send</button>

<script>
    const socket = new WebSocket("ws://localhost:8080/ws");

    function sendMessage() {
        const messageInput = document.getElementById("messageInput");
        const message = messageInput.value;
        socket.send(message);
        messageInput.value = "";
    }
</script>
</body>
</html>

用戶客戶端 Client.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta >
    <title>Client Panel</title>
</head>
<body>
<ul id="messages"></ul>

<script>
    const socket = new WebSocket("ws://localhost:8080/ws");

    socket.onmessage = function(event) {
        const messages = document.getElementById("messages");
        console.log(messages)
        const li = document.createElement("li");
        li.textContent = event.data;
        messages.appendChild(li);
    };
</script>
</body>
</html>

啓動服務器

多打開幾個用戶客戶端 Client.html

一開始都是空白的,因爲運營端還沒有推消息

打開運營端 Admin.html

開始推送消息給在線的客戶端

比如推送下面的標題:

"突發!全球首次太空旅遊航班成功完成,乘客欣賞到地球升起和日落的壯麗景色!"

總結

案例雖然簡單,但卻是核心理論的體現,如果是線上環境開發需要注意客戶端在線用戶的存儲 redis,mysql 等等都可以,希望對大家在某個維度可以幫助到大家。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/WiuiNkg-Bq_i9xJzawVsxA