首页 > 后端开发 > Golang > 使用 WebSocket 的实时 Web 应用程序演示 - 后端

使用 WebSocket 的实时 Web 应用程序演示 - 后端

Patricia Arquette
发布: 2024-12-30 11:52:14
原创
1017 人浏览过

Real-Time Web Application demo with WebSocket - Backend

介绍

在本文中,我将探索实时 WebSocket 应用程序的后端实现。使用 Gin 和 Go 构建的后端可以有效管理 WebSocket 连接、存储消息并向所有连接的客户端广播更新。


项目结构

https://github.com/tom-takeru/web-socket-demo

我的后端项目的组织方式是为了确保模块化和可重用性。以下是更新后的目录结构:

./backend
├── go.mod
├── go.sum
├── main.go
└── stores
    └── messages.go
登录后复制

关键目录和文件

  • go.mod:定义模块依赖项和版本。
  • main.go:初始化 WebSocket 服务器和路由的应用程序入口点。
  • stores/messages.go:通过线程安全操作管理消息存储。

核心组件:main.go

main.go 是我的 WebSocket 服务器应用程序的主要入口点。它设置 Gin 路由器,定义 WebSocket 路由,并处理 WebSocket 生命周期。

代码演练

package main

import (
    "encoding/json"
    "net/http"
    "sync"
    "time"

    "github.com/gin-gonic/gin"
    "github.com/gorilla/websocket"

    "github.com/tom-takeru/web-socket-demo/backend/stores"
)

var (
    upgrader = websocket.Upgrader{
        CheckOrigin: func(r *http.Request) bool {
            origin := r.Header.Get("Origin")
            // NOTE: This project is for local development only.
            return origin == "http://localhost:3000"
        },
    }
    messageStore = stores.NewMessageStore()
    clients      = make(map[*websocket.Conn]bool)
    clientsMu    sync.Mutex
)

func handleWebSocket(c *gin.Context) {
    conn, err := upgrader.Upgrade(c.Writer, c.Request, nil)
    if err != nil {
        c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to upgrade to WebSocket"})
        return
    }
    defer conn.Close()

    clientsMu.Lock()
    clients[conn] = true
    clientsMu.Unlock()

    // Send existing messages to the new connection
    for _, msg := range messageStore.MarshalMessages() {
        conn.WriteMessage(websocket.TextMessage, msg)
    }

    for {
        _, message, err := conn.ReadMessage()
        if err != nil {
            break
        }

        var msgData map[string]string
        if err := json.Unmarshal(message, &msgData); err != nil {
            break
        }

        timestamp := time.Now().Format(time.RFC3339)
        msgData["timestamp"] = timestamp

        messageStore.AddMessage(msgData)

        modifiedMessage, err := json.Marshal(msgData)
        if err != nil {
            break
        }

        clientsMu.Lock()
        for client := range clients {
            if err := client.WriteMessage(websocket.TextMessage, modifiedMessage); err != nil {
                client.Close()
                delete(clients, client)
            }
        }
        clientsMu.Unlock()
    }

    clientsMu.Lock()
    delete(clients, conn)
    clientsMu.Unlock()
}

func main() {
    r := gin.Default()
    r.GET("/ws", handleWebSocket)
    r.Run("localhost:8080")
}
登录后复制

关键功能

  1. 状态管理:跟踪连接的客户端并使用互斥体确保线程安全访问。
  2. WebSocket 生命周期:处理连接设置、消息广播和断开连接时的清理。

结论

我的 WebSocket 演示应用程序的后端实现演示了如何使用 Gin 和 Go 有效管理实时通信。通过利用 WebSocket 实现持久连接和线程安全消息存储,该应用程序为构建实时 Web 应用程序奠定了坚实的基础。

在下一篇文章中,我将讨论部署策略和优化 WebSocket 性能。


系列链接

  • 使用 WebSocket 的实时 Web 应用程序演示 - 概述
  • 使用 WebSocket 的实时 Web 应用程序演示 - 前端

以上是使用 WebSocket 的实时 Web 应用程序演示 - 后端的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:dev.to
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板