【Gin框架入门到精通系列15】Gin框架中的WebSocket实时通信

[go]引入websocket并基于redis实现消息发送 消息通信功能一共三步1、建立路由接口2、初始化信息3、循环监听通道读取消息和循环读取通道发送消息。 阅读详情
AI摘要

本文聚焦Gin框架中的WebSocket实时通信。先介绍WebSocket协议原理、特点、与HTTP区别及工作机制,接着说明Go语言对其支持,重点展示在Gin框架集成该功能,构建实时聊天应用,还添加私聊、消息持久化等高级功能,最后给出连接管理、安全及性能优化技巧。

📚 原创系列: “Gin框架入门到精通系列”

🔄 转载说明: 本文最初发布于"Gopher部落"微信公众号,经原作者授权转载。

🔗 关注原创: 欢迎扫描文末二维码,关注"Gopher部落"微信公众号获取第一手Gin框架技术文章。

📑 Gin框架学习系列导航

本文是【Gin框架入门到精通系列15】的第15篇 - Gin框架中的WebSocket实时通信

高级特性篇
  1. Gin框架中的国际化与本地化
  2. Gin框架中的WebSocket实时通信👈 当前位置
  3. Gin框架的优雅关闭与热重启
  4. Gin框架的请求限流与熔断

🔍 查看完整系列文章

📖 文章导读

在现代Web应用中,实时通信已成为提升用户体验的关键因素。传统的HTTP协议基于请求-响应模式,不适合实时交互场景。WebSocket作为一种新的网络协议,为Web应用提供了全双工通信能力,使服务器能够主动向客户端推送数据,实现真正的实时通信。

一、引言

1.1 知识点概述

在现代Web应用中,实时通信已成为提升用户体验的关键因素。传统的HTTP协议基于请求-响应模式,不适合实时交互场景。WebSocket作为一种新的网络协议,为Web应用提供了全双工通信能力,使服务器能够主动向客户端推送数据,实现真正的实时通信。

本文将详细介绍WebSocket协议的原理,并展示如何在Gin框架中集成WebSocket功能,构建一个功能完善的实时聊天应用。通过学习本文内容,你将掌握:

  1. WebSocket协议的基本原理和工作机制
  2. WebSocket与HTTP的区别和联系
  3. 在Gin框架中集成gorilla/websocket库
  4. 实现WebSocket连接的建立、消息发送和接收
  5. 构建一个完整的实时聊天室应用
  6. WebSocket连接管理和性能优化策略

1.2 学习目标

完成本篇学习后,你将能够:

  • 理解WebSocket协议的技术原理和应用场景
  • 在Gin框架中正确集成WebSocket功能
  • 实现基本的实时通信功能,如广播、私聊等
  • 处理WebSocket连接的生命周期管理
  • 开发实时应用的常见模式和最佳实践

1.3 预备知识

在学习本文内容前,你需要具备以下知识:

  • 熟悉Go语言基础语法
  • 了解Gin框架的基本使用
  • 掌握HTTP协议的基本知识
  • 基本的并发编程概念
  • 了解通道(Channel)和Goroutine的使用

二、理论讲解

2.1 WebSocket协议概述

2.1.1 WebSocket协议的起源与发展

WebSocket协议最初由Ian Hickson在2008年提出,并于2011年成为RFC 6455标准。该协议的设计目的是解决Web应用中的实时通信问题,为浏览器和服务器之间提供一种更有效的通信机制。

在WebSocket出现之前,开发者通常使用以下技术模拟实时通信:

  • 轮询(Polling): 客户端定期向服务器发送请求,检查是否有新数据
  • 长轮询(Long Polling): 服务器保持请求开放直到有新数据或超时
  • 服务器发送事件(Server-Sent Events): 允许服务器推送数据到客户端,但仍基于HTTP

这些方法都有各自的局限性,如效率低下、资源消耗大、延迟高等。WebSocket协议通过建立持久连接,解决了这些问题,使真正的双向实时通信成为可能。

2.1.2 WebSocket的技术特点

WebSocket具有以下核心特性:

  1. 全双工通信: 支持客户端和服务器之间的双向通信,双方可以同时发送和接收数据
  2. 单一TCP连接: 通信双方建立一次连接后保持长期开放,避免频繁的连接建立和断开
  3. 低延迟: 数据传输的延迟显著降低,适合实时应用
  4. 高效传输: 相比HTTP协议,WebSocket的数据包头部更小,减少了带宽消耗
  5. 基于事件的模型: 通过事件监听机制处理消息,更符合实时应用的设计模式
  6. 原生支持: 现代浏览器都内置支持WebSocket协议,无需额外插件
2.1.3 WebSocket与HTTP的区别与联系

WebSocket与HTTP的关系密切但也有显著区别:

联系:

  • WebSocket使用HTTP进行初始握手
  • 使用相同的端口(80和443),便于穿透防火墙
  • URI模式相似(ws://和wss://对应http://和https://)

区别:

特性 HTTP WebSocket
通信方式 单向(请求-响应) 双向(全双工)
连接特性 无状态,短连接 有状态,长连接
数据格式 基于文本的请求和响应 支持文本和二进制数据
开销 每次请求都有HTTP头部 建立连接后的消息开销小
实时性 依赖轮询或其他技术 原生支持实时推送
状态管理 无内置状态,依赖Cookie等 连接本身维护状态

2.2 WebSocket的工作原理

2.2.1 WebSocket握手过程

WebSocket连接建立需要通过一个特殊的HTTP握手过程,主要步骤如下:

  1. 客户端发起请求:

    GET /chat HTTP/1.1
    Host: server.example.com
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
    Origin: http://example.com
    Sec-WebSocket-Version: 13
    
  2. 服务器响应:

    HTTP/1.1 101 Switching Protocols
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
    
  3. 连接建立:
    一旦握手成功,HTTP协议升级为WebSocket协议,之后的通信不再使用HTTP,而是使用WebSocket的数据帧格式。

关键字段解释:

  • Upgrade: websocket: 表示请求升级到WebSocket协议
  • Connection: Upgrade: 告知服务器处理协议升级
  • Sec-WebSocket-Key: 客户端生成的随机密钥
  • Sec-WebSocket-Accept: 服务器根据客户端密钥计算的响应值
2.2.2 WebSocket数据帧格式

WebSocket通信使用特定的数据帧格式,与HTTP完全不同:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-------+-+-------------+-------------------------------+
|F|R|R|R| opcode|M| Payload len |    Extended payload length    |
|I|S|S|S|  (4)  |A|     (7)     |             (16/64)           |
|N|V|V|V|       |S|             |   (if payload len==126/127)   |
| |1|2|3|       |K|             |                               |
+-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
|     Extended payload length continued, if payload len == 127  |
+ - - - - - - - - - - - - - - - +-------------------------------+
|                               |Masking-key, if MASK set to 1  |
+-------------------------------+-------------------------------+
| Masking-key (continued)       |          Payload Data         |
+-------------------------------- - - - - - - - - - - - - - - - +
:                     Payload Data continued ...                :
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
|                     Payload Data continued ...                |
+---------------------------------------------------------------+

重要组成部分:

  • FIN(1位): 标识这是否为消息的最后一个片段
  • Opcode(4位): 定义数据的类型(0x1为文本,0x2为二进制)
  • MASK(1位): 表示有效载荷是否经过掩码处理
  • Payload length(7位、7+16位或7+64位): 有效载荷的长度
  • Masking-key(0或4字节): 用于解码有效载荷的密钥
  • Payload data: 实际传输的数据内容
2.2.3 WebSocket生命周期

WebSocket连接的完整生命周期包括以下阶段:

  1. 连接建立: 通过HTTP握手升级到WebSocket协议
  2. 数据传输: 双方可以随时发送或接收消息
  3. 心跳检测: 定期发送Ping/Pong帧确保连接活跃
  4. 错误处理: 处理网络异常、超时等错误情况
  5. 连接关闭: 任一方可以发送关闭帧,完成有序关闭

关闭码(Close Code)在关闭连接时用于表明关闭原因:

  • 1000: 正常关闭
  • 1001: 端点离开(如服务器关闭或浏览器导航离开)
  • 1002: 协议错误
  • 1003: 接收到不可接受的数据类型
  • 1006: 异常关闭(连接非正常终止)
  • 1007: 数据类型不一致
  • 1008: 策略违规
  • 1009: 消息过大
  • 1010: 需要扩展(客户端)
  • 1011: 意外情况(服务器)

2.3 WebSocket应用场景

WebSocket技术特别适合以下应用场景:

2.3.1 实时通信应用
  • 聊天应用: 即时消息传递、群聊、私聊
  • 协作工具: 多人编辑、实时协作文档
  • 社交媒体: 实时通知、动态更新
  • 客户支持系统: 实时客服聊天
2.3.2 实时数据更新
  • 金融应用: 股票价格、货币汇率实时更新
  • 体育应用: 比分实时更新、赛事直播
  • 监控系统: 服务器状态、网络流量实时监控
  • 物联网应用: 传感器数据实时显示
2.3.3 多人在线游戏
  • 多人对战游戏: 实时同步游戏状态
  • 在线棋牌游戏: 玩家间的实时交互
  • 游戏大厅: 在线状态、匹配系统
2.3.4 流媒体应用
  • 实时视频会议: WebRTC结合WebSocket实现信令
  • 直播平台: 弹幕系统、观众互动
  • 实时通知系统: 推送重要事件和通知

2.4 Go语言中的WebSocket支持

Go语言社区提供了多个WebSocket库,其中最常用的是gorilla/websocket。

2.4.1 gorilla/websocket库简介

gorilla/websocket是Go语言中最流行的WebSocket实现,提供了完整的WebSocket协议支持,特点包括:

  • 完全实现RFC 6455标准
  • 简洁易用的API
  • 高性能设计
  • 支持各种WebSocket特性(子协议协商、压缩等)
  • 广泛的测试覆盖
  • 活跃的社区维护
2.4.2 其他WebSocket实现

除了gorilla/websocket,Go还有其他WebSocket库:

  • golang.org/x/net/websocket: Go标准库的子包,但功能较简单,不推荐用于生产环境
  • nhooyr.io/websocket: 较新的库,注重性能和安全性
  • gobwas/ws: 专注于性能的低级WebSocket库
2.4.3 Gin框架中集成WebSocket

Gin本身不直接提供WebSocket支持,但可以轻松集成gorilla/websocket库。集成的基本步骤:

  1. 安装gorilla/websocket:

    go get github.com/gorilla/websocket
    
  2. 在Gin路由中设置WebSocket处理器:

    var upgrader = websocket.Upgrader{
         
         
        ReadBufferSize:  1024,
        WriteBufferSize: 1024,
        CheckOrigin: func(r *http.Request) bool {
         
         
            return true  // 允许所有跨域请求,生产环境应当限制
        },
    }
    
    func handleWebSocket(c *gin.Context) {
         
         
        conn, err := upgrader.Upgrade(c.Writer, c.Request, nil)
        if err != nil {
         
         
            return
        }
        defer conn.Close()
    
        // 处理WebSocket连接...
    }
    
    func main() {
         
         
        r := gin.Default()
        r.GET("/ws", handleWebSocket)
        r.Run(":8080")
    }
    

在下一节中,我们将通过实践代码,详细展示如何在Gin框架中实现WebSocket服务,并构建一个功能完整的实时聊天应用。

三、代码实践

在这一部分,我们将通过一系列实际代码示例,展示如何在Gin框架中集成WebSocket功能,并逐步构建一个实时聊天应用。

3.1 基础WebSocket服务器

首先,我们来创建一个最简单的WebSocket服务器,它能够接受连接并与客户端进行消息交换。

3.1.1 项目初始化

首先创建项目目录并初始化Go模块:

mkdir gin-websocket-demo
cd gin-websocket-demo
go mod init gin-websocket-demo

安装必要的依赖:

go get github.com/gin-gonic/gin
go get github.com/gorilla/websocket
3.1.2 基础WebSocket服务实现

下面是一个基本的WebSocket服务器实现,支持连接建立和简单的消息收发:

// main.go
package main

import (
	"log"
	"net/http"

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

// 配置WebSocket upgrader
var upgrader = websocket.Upgrader{
   
   
	ReadBufferSize:  1024,
	WriteBufferSize: 1024,
	// 允许所有CORS请求,生产环境应当配置更严格的规则
	CheckOrigin: func(r *http.Request) bool {
   
   
		return true
	},
}

// WebSocket处理函数
func handleWebSocket(c *gin.Context) {
   
   
	// 将HTTP连接升级为WebSocket连接
	conn, err := upgrader.Upgrade(c.Writer, c.Request, nil)
	if err != nil {
   
   
		log.Printf("升级连接失败: %v", err)
		return
	}
	defer conn.Close()

	log.Printf("客户端已连接: %s", c.Request.RemoteAddr)

	// 向客户端发送欢迎消息
	if err := conn.WriteMessage(websocket.TextMessage, []byte("欢迎连接到WebSocket服务器!")); err != nil {
   
   
		log.Println("写入消息失败:", err)
		return
	}

	// 持续读取客户端消息
	for {
   
   
		// 读取消息
		messageType, message, err := conn.ReadMessage()
		if err != nil {
   
   
			log.Println("读取消息错误:", err)
			break
		}

		// 记录收到的消息
		log.Printf("收到消息: %s", message)

		// 将消息发送回客户端(回显)
		if err := conn.WriteMessage(messageType, message); err != nil {
   
   
			log.Println("写入消息失败:", err)
			break
		}
	}

	log.Printf("客户端断开连接: %s", c.Request.RemoteAddr)
}

func main() {
   
   
	// 创建Gin路由
	r := gin.Default()

	// 提供WebSocket端点
	r.GET("/ws", handleWebSocket)

	// 提供一个简单的HTML页面用于测试
	r.GET("/", func(c *gin.Context) {
   
   
		c.File("index.html")
	})

	// 启动服务器
	log.Println("服务器启动在 http://localhost:8080")
	if err := r.Run(":8080"); err != nil {
   
   
		log.Fatal("启动服务器失败:", err)
	}
}
3.1.3 客户端测试页面

创建一个简单的HTML页面(index.html)用于测试WebSocket连接:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>WebSocket测试</title>
    <style>
        body {
     
     
            font-family: Arial, sans-serif;
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
        }
        #messages {
     
     
            height: 300px;
            border: 1px solid #ddd;
            padding: 10px;
            overflow-y: scroll;
            margin-bottom: 20px;
            background-color: #f9f9f9;
        }
        #messageInput {
     
     
            padding: 10px;
            width: 70%;
        }
        button {
     
     
            padding: 10px 15px;
            background-color: #4CAF50;
            color: white;
            border: none;
            cursor: pointer;
        }
        .status {
     
     
            margin-bottom: 10px;
            padding: 5px;
        }
        .connected {
     
     
            background-color: #dff0d8;
            color: #3c763d;
        }
        .disconnected {
     
     
            background-color: #f2dede;
            color: #a94442;
        }
        .message {
     
     
            margin: 5px 0;
            padding: 5px;
            border-bottom: 1px solid #eee;
        }
        .sent {
     
     
            text-align: right;
            color: #0066cc;
        }
        .received {
     
     
            text-align: left;
            color: #006600;
        }
    </style>
</head>
<body>
    <h1>WebSocket测试页面</h1>
    
    <div id="status" class="status disconnected">未连接</div>
    
    <div id="messages"></div>
    
    <div>
        <input type="text" id="messageInput" placeholder="输入消息..." disabled>
        <button id="sendButton" disabled>发送</button>
        <button id="connectButton">连接</button>
        <button id="disconnectButton" disabled>断开</button>
    </div>
    
    <script>
        // DOM元素
        const statusDiv = document.getElementById('status');
        const messagesDiv = document.getElementById('messages');
        const messageInput = document.getElementById('messageInput');
        const sendButton = document.getElementById('sendButton');
        const connectButton = document.getElementById('connectButton');
        const disconnectButton = document.getElementById('disconnectButton');
        
        // WebSocket连接
        let socket = null;
        
        // 添加消息到消息区
        function addMessage(message, type) {
     
     
            const messageElement = document.createElement('div');
            messageElement.classList.add('message', type);
            messageElement.textContent = message;
            messagesDiv.appendChild(messageElement);
            messagesDiv.scrollTop = messagesDiv.scrollHeight;
        }
        
        // 连接WebSocket
        function connect() {
     
     
            // 创建WebSocket连接
            const wsProtocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
            const wsUrl = `${ 
       wsProtocol}//${ 
       window.location.host}/ws`;
            
            socket = new WebSocket(wsUrl);
            
            // 连接打开事件
            socket.onopen = function(e) {
     
     
                statusDiv.textContent = '已连接';
                statusDiv.className = 'status connected';
                
                // 启用输入和发送按钮
                messageInput.disabled = false;
                sendButton.disabled = false;
                connectButton.disabled = true;
                disconnectButton.disabled = false;
                
                addMessage('连接已建立', 'system');
            };
            
            // 接收消息事件
            socket.onmessage = function(event) {
     
     
                addMessage(`服务器: ${ 
       event.data}`, 'received');
            };
            
            // 连接关闭事件
            socket.onclose = function(event) {
     
     
                statusDiv.textContent = '已断开连接';
                statusDiv.className = 'status disconnected';
                
                // 禁用输入和发送按钮
                messageInput.disabled = true;
                sendButton.disabled = true;
                connectButton.disabled = false;
                disconnectButton.disabled = true;
                
                const reason = event.reason ? `原因: ${ 
       event.reason}` : '';
                addMessage(`连接已关闭。代码: ${ 
       event.code} ${ 
       reason}`, 'system');
            };
            
            // 连接错误事件
            socket.onerror = function(error) {
     
     
                statusDiv.textContent = '连接错误';
                statusDiv.className = 'status disconnected';
                addMessage('连接发生错误', 'system');
                console.error('WebSocket错误:', error);
            };
        }
        
        // 断开连接
        function disconnect() {
     
     
            if (socket) {
     
     
                socket.close(1000, "用户主动断开");
                socket = null;
            }
        }
        
        // 发送消息
        function sendMessage() {
     
     
            const message = messageInput.value;
            if (message && socket) {
     
     
                socket.send(message);
                addMessage(`我: ${ 
       message}`, 'sent');
                messageInput.value = '';
            }
        }
        
        // 事件监听
        connectButton.addEventListener('click', connect);
        disconnectButton.addEventListener('click', disconnect);
        sendButton.addEventListener('click', sendMessage);
        
        // 按回车键发送消息
        messageInput.addEventListener('keypress', function(e) {
     
     
            if (e.key === 'Enter') {
     
     
                sendMessage();
            }
        });
    </script>
</body>
</html>
3.1.4 运行和测试

运行应用并在浏览器中测试:

go run main.go
  1. 打开浏览器访问 http://localhost:8080
  2. 点击"连接"按钮建立WebSocket连接
  3. 在输入框中输入消息并发送
  4. 观察服务器如何回显消息

这个简单的例子展示了WebSocket的基本工作原理:

  • 建立双向通信通道
  • 服务器可以主动向客户端发送消息
  • 客户端可以随时向服务器发送消息
  • 连接保持开放直到任一方断开

3.2 构建实时聊天室应用

接下来,我们将扩展基础示例,构建一个功能更完善的聊天室应用,支持多用户、消息广播、用户列表等功能。

3.2.1 聊天室结构设计

聊天室应用需要管理多个WebSocket连接,处理消息广播和用户状态。我们将创建以下核心结构:

  1. Client: 表示单个WebSocket连接的客户端
  2. ChatRoom: 管理所有客户端,处理消息广播
  3. Message: 定义聊天消息的格式

下面是完整的聊天室实现:

// main.go
package main

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

	"github.com/gin-gonic/gin"
	"github.com/google/uuid"
	"github.com/gorilla/websocket"
)

// 配置WebSocket upgrader
var upgrader = websocket.Upgrader{
   
   
	ReadBufferSize:  1024,
	WriteBufferSize: 1024,
	Check
gin框架接入websocket服务 路径的GET请求处理函数。在该处理函数中,我们将HTTP连接升级为WebSocket连接。然后,我们循环读取来自客户端的消息,并将其原样发送回客户端。当使用Gin框架实现WebSocket服务器的Go部分时,你需要在项目中导入。创建了一个默认的Gin路由引擎,你可以根据需要进行进一步的自定义和路由定义。在这个示例中,我们使用Gin框架创建了一个路由组,并定义了。运行以上代码后,WebSocket服务器将在。路径上的WebSocket连接请求。请注意,示例代码中使用了。 阅读详情

相关推荐

gin框架中结合gorilla实现webSocket

gin框架写rest接口特别6,性能也很好。 本文介绍一下gin和gorilla结合创建websocket 1. gin github地址:https://github.com/gin-gonic/gin 安装gin的代码包 go get github.com/gin-gonic/gin package main import ( "github.com/...

lihao19910921的专栏 9591

gin+websocket+mongodb实现 IM 即时聊天系统,基于WS连接的即时聊天

gin+websocket+mongodb实现 IM 即时聊天系统,基于WS连接的即时聊天

Mac 环境配置jdk、Maven

3、终端打开配置jdk时候建好的脚本文件: open -e .bash_profile。4、查看maven是否安装成功和系统能不能识别maven/mvn命令:⬇️。输入⬇️并保存: 其中第一行JAVA_HOME替换为自己下的jdk路径。,安装编译好的二进制版本,具体安装zip还是tar.gz我看的。5、查看jdk是否安装成功和系统能不能识别java命令:⬇️。至此,我的Mac系统的环境配置jdk、Maven完成!然后就发现我的maven命令还是没作用,不识别,下载后直接安装即可,很快,点几下就OK了。

weixin_42416791的博客 4395

天线学习笔记——串馈网络设计

工程中通常更倾向于使用50Ω、70.7Ω、100Ω的固定阻抗的带宽,实际中可以分别使用固定阻抗的带宽和计算得到的带宽进行仿真,观察二者的性能,取性能更优者即可。本系列是一个记录天线设计的笔记,分享出来也希望能够帮助到大家,后续本系列文章还会不定期更新,如有需要可关注,任何问题均可在评论区或私信提出,看到必回。如果对大家有帮助可进行打赏哦~

Ethan的博客 7877

Unity UI Toolkit避坑指南:从官方Samples到实际项目,这些‘坑’我帮你踩过了

本文分享了Unity UI Toolkit在实际项目中的避坑经验和优化技巧,包括动画系统的高效替代方案、3D世界UI的创新实现方式、USS样式继承的反直觉规则等。通过详细的代码示例和性能优化策略,帮助开发者避免常见陷阱,提升开发效率。

weixin_29535577的博客 342

手把手教你用STM32硬件SPI驱动BMI088陀螺仪(附完整代码)

本文提供了一份详尽的STM32硬件SPI驱动BMI088陀螺仪的实战指南。内容涵盖从硬件连接、SPI底层配置、驱动层封装到设备初始化、数据读取与同步策略,并深入探讨了数据处理、滤波融合及温度补偿等核心技巧,旨在帮助开发者构建稳定高效的IMU驱动框架,解决BMI088应用中常见的挑战。

quiet的专栏 529

coreldraw sp2精简版 x4_CorelDRAW X4下载-CorelDRAW X4 SP2 精简版_Win10镜像官网

CorelDRAW X4 SP2是一个专业图形设计软件,专用于矢量图形编辑与排版,借助其丰富的内容和专业图形设计、照片编辑和网站设计软件,您将能够随心所欲地表达自己的风格与创意,轻松创作徽标标志、广告标牌、车身贴和传单、模型绘制、插图描画、排版及分色输出等。CorelDRAW X4 SP2软件特色CorelDraw X4 相比两年前的 CorelDraw X3 加入了大量新特性,总计有50项以上,...

weixin_30346025的博客 8893

风-车-桥耦合随机振动预测框架:从物理模型到高效代理

本文提出了一种风-车-桥耦合随机振动预测的混合框架,结合物理模型与代理模型实现高效计算。该框架的核心数学本质是时变参数-随机激励-高维动力系统,主要解决三大计算难点:自由度规模悬殊、时变特性和随机性传播。系统采用分层解耦-代理加速的技术路线,底层基于物理模型建立车辆运动方程和桥梁运动方程,上层通过深度学习代理实现随机激励到响应的端到端映射。文中详细介绍了随机激励建模(包括脉动风速和路面不平度)、子系统建模、耦合求解方法,并提供了可运行的Python代码实现。该框架可显著提高风-车-桥系统随机振动分析的效率,

huanghm88的专栏 102

【WRF-Urban数据集】中国60个城市的1 km分辨率城市冠层参数(UCPs)

中国60个城市的1 km分辨率城市冠层参数(UCPs)

WW、forever的博客 1063

【用unity实现100个游戏之18】从零开始制作一个类CSGO/CS2、CF第一人称FPS射击游戏——基础篇1(附项目源码)

生存和射击游戏一直是我的最爱,说起3D最普遍的应该就是射击系统了,你可以在任何情况下加入射击功能,所以我写下了这篇FPS开发记录。希望对你有帮助。在这个项目中,你将学习如何设计和实现射击系统、武器系统、玩家控制、场景设计等方面的内容。通过这个项目,你将深入了解游戏开发中的许多核心概念和技术,并且在实践中不断提升自己。本项目将带你从零开始逐步实现一个完整的第一人称射击游戏,并且会逐步引入一些高级功能,如特效、声音等。

向宇的博客,专注php/web全栈 unity游戏开发,欢迎大家评论纠错 5499

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

上一篇: 【Gin框架入门到精通系列14】Gin框架中的国际化与本地化
下一篇: 【Gin框架入门到精通系列16】Gin框架的优雅关闭与热重启
Gopher部落
博客等级 码龄2年 784粉丝 92原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Gopher部落

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值