This is an explanation of the video content.
 用技术延续对ACG的热爱
3

 |   | 

使用go的websocket实现一对多聊天

在实现一对多聊天服务时,服务器需要能够接收来自一个用户的消息,并将其广播给多个其他用户。以下是使用Go语言和WebSocket实现一对多聊天服务的示例:

服务器端代码:

package main

import (
    "log"
    "net/http"
    "sync"
    "github.com/gorilla/websocket"
)

var upgrader = websocket.Upgrader{
    CheckOrigin: func(r *http.Request) bool {
        return true
    },
}

// 用于存储活跃的WebSocket连接和用户ID的映射
var connections = make(map[string]*websocket.Conn)
var mu sync.Mutex

func handleConnections(w http.ResponseWriter, r *http.Request) {
    // 升级HTTP连接到WebSocket
    ws, err := upgrader.Upgrade(w, r, nil)
    if err != nil {
        log.Println("升级错误:", err)
        return
    }
    defer ws.Close()

    // 从请求中获取用户ID
    userID := r.URL.Query().Get("userID")
    if userID == "" {
        log.Println("缺少用户ID")
        return
    }

    mu.Lock()
    connections[userID] = ws
    mu.Unlock()

    for {
        _, msg, err := ws.ReadMessage()
        if err != nil {
            log.Println("读取消息失败:", err)
            mu.Lock()
            delete(connections, userID)
            mu.Unlock()
            break
        }

        // 广播消息给所有连接
        mu.Lock()
        for id, conn := range connections {
            if id != userID { // 发送消息给除了自己之外的所有用户
                if err := conn.WriteMessage(websocket.TextMessage, msg); err != nil {
                    log.Println("发送消息失败:", err)
                    delete(connections, id)
                }
            }
        }
        mu.Unlock()
    }
}

func main() {
    http.HandleFunc("/ws", handleConnections)
    log.Println("WebSocket服务器启动在8080端口...")
    if err := http.ListenAndServe(":8080", nil); err != nil {
        log.Fatal("ListenAndServe: ", err)
    }
}

客户端代码(HTML + JavaScript):

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>WebSocket Group Chat</title>
</head>
<body>
    <input type="text" id="messageInput" placeholder="Type a message">
    <button id="sendButton">Send</button>
    <script>
        const userID = prompt('Enter your User ID:');
        const ws = new WebSocket('ws://localhost:8080/ws?userID=' + encodeURIComponent(userID));

        const messageInput = document.getElementById('messageInput');
        const sendButton = document.getElementById('sendButton');

        ws.onmessage = function(event) {
            console.log('Received message:', event.data);
            // 将接收到的消息显示在页面上或其他逻辑
        };

        sendButton.addEventListener('click', function() {
            const message = messageInput.value;
            ws.send(message);
            messageInput.value = '';
        });
    </script>
</body>
</html>

说明:

  1. 服务器端

    • 使用gorilla/websocket库来升级HTTP连接到WebSocket,并管理所有活跃的WebSocket连接。
    • 使用互斥锁sync.Mutex来确保连接映射的线程安全。
    • 当服务器接收到消息时,它会遍历所有连接,并发送消息给除自己之外的所有用户。
  2. 客户端

    • 通过URL参数传递用户ID。
    • 当用户点击发送按钮时,客户端将消息发送到服务器。

这个示例实现了一个基本的一对多聊天服务,其中服务器负责接收消息并广播给所有其他用户。客户端负责发送和接收消息。

3 服务端 ↦ Go从0到1手把手教程 __ 246 字
 Go从0到1手把手教程 #18