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

 |   | 

使用go的websocket实现点对点聊天

使用Go语言和WebSocket实现点对点聊天服务,需要考虑以下几个关键步骤:

  1. 建立WebSocket连接:客户端通过WebSocket与服务器建立连接。
  2. 身份验证:客户端连接时需要提供标识身份的信息,例如用户名或用户ID。
  3. 连接管理:服务器需要维护一个映射,以关联WebSocket连接和用户身份。
  4. 消息路由:服务器接收到消息后,根据目标用户身份将消息转发到正确的WebSocket连接。
  5. 断开连接处理:当客户端断开连接时,服务器需要从映射中移除对应的条目。

以下是一个简化的示例实现:

服务器端代码:

package main

import (
    "log"
    "net/http"
    "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)

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
    }

    // 将连接和用户ID关联
    connections[userID] = ws

    // 处理消息
    go func() {
        for {
            _, msg, err := ws.ReadMessage()
            if err != nil {
                log.Println("读取消息失败:", err)
                delete(connections, userID) // 删除连接
                break
            }

            // 根据消息中的目标用户ID转发消息
            targetID := parseTargetID(msg)
            if targetID != "" {
                targetConn, ok := connections[targetID]
                if ok {
                    if err := targetConn.WriteMessage(websocket.TextMessage, msg); err != nil {
                        log.Println("发送消息失败:", err)
                        delete(connections, targetID) // 删除目标连接
                    }
                }
            }
        }
    }()
}

func parseTargetID(msg []byte) string {
    // 解析消息以获取目标用户ID
    // 这里需要根据实际的消息格式实现解析逻辑
    return string(msg) // 示例:直接返回消息内容作为目标ID
}

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 P2P Chat</title>
</head>
<body>
    <input type="text" id="messageInput" placeholder="Type a message">
    <button id="sendButton">Send</button>
    <input type="text" id="targetUserID" placeholder="Target User ID">
    <script>
        const ws = new WebSocket('ws://localhost:8080/ws?userID=' + encodeURIComponent(prompt('Enter your User ID:')));

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

        document.getElementById('sendButton').addEventListener('click', function() {
            const messageInput = document.getElementById('messageInput');
            const targetUserID = document.getElementById('targetUserID').value;
            const message = messageInput.value;

            // 发送消息,消息内容中包含目标用户ID
            ws.send(targetUserID + ' ' + message);
            messageInput.value = '';
        });
    </script>
</body>
</html>

说明:

  • 服务器端使用gorilla/websocket库来升级HTTP连接到WebSocket,并管理所有活跃的WebSocket连接。
  • 客户端通过URL参数传递用户ID,并在发送消息时包含目标用户ID。
  • 服务器接收到消息后,解析目标用户ID并转发消息到相应的WebSocket连接。
  • 这里的parseTargetID函数是一个示例,你需要根据实际的消息格式实现解析逻辑。

38 服务端 ↦ Go从0到1手把手教程 __ 276 字
 Go从0到1手把手教程 #14