golang Gin实现websocket
golang使用 Gin实现 websocket,这里笔者重新搭建一个项目
1、创建项目安装依赖
项目名为 go-gin-websocket
在指定文件夹下,新建项目文件夹 go-gin-websocket

进入项目文件夹,打开cmd窗口,在项目(go-gin-websocket)文件夹路径下,执行初始化命令 go mod init go-gin-websocket
go mod init go-gin-websocket

安装依赖
安装gin
go get -u github.com/gin-gonic/gin
安装websocket
go get github.com/gorilla/websocket

2、搭建项目
在项目目录下新建controller、static、templates、ws文件夹,分别用来存放controller代码、静态文件、页面、websocket代码

在templates目录下新建 index.html页面
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
hello
<script>var webSocket;try {webSocket = new WebSocket('ws://127.0.0.1:8080/ws?id=abc123456789');}catch (e) {console.log(e)}webSocket.onerror = function(event) {}//与WebSocket建立连接webSocket.onopen = function(event) {console.log('建立连接')console.log(JSON.stringify(event))var msg = "身无彩凤双飞翼,心有灵犀一点通"//发送消息webSocket.send(msg);};//接收服务端发送的消息webSocket.onmessage=function (m) {console.log(m)console.log(m.data)}
</script>
</body>
</html>
在controller目录下新建 page_controller.go
package controllerimport "github.com/gin-gonic/gin"func Index(c *gin.Context) {c.HTML(200, "index.html", nil)
}
在ws目录下新建 websocket.go
package wsimport ("fmt""github.com/gin-gonic/gin""github.com/gorilla/websocket""log""net/http"
)func InitWebSocket(c *gin.Context) {var upgrader = websocket.Upgrader{ReadBufferSize: 1024,WriteBufferSize: 1024,CheckOrigin: func(r *http.Request) bool {log.Println("升级协议", r.Header["User-Agent"])return true},}conn, err := upgrader.Upgrade(c.Writer, c.Request, nil)if err != nil {log.Println(err)return}defer conn.Close()userId := c.Query("id")log.Println("用户id:", userId)for {mt, message, err := conn.ReadMessage()log.Println("获取客户端发送的消息:" + string(message))fmt.Println(mt)if err != nil {log.Println(err)break}var msg = "春风得意马蹄疾,一日看尽长安花"err2 := conn.WriteMessage(websocket.TextMessage, []byte(msg))if err2 != nil {log.Println("write:", err2)break}}}
在项目根目录下新建 main.go

main.go内容
package mainimport ("github.com/gin-gonic/gin""go-gin-websocket/controller""go-gin-websocket/ws"
)func main() {e := gin.Default()//html页面位置e.LoadHTMLGlob("templates/*")//静态文件位置e.Static("/static", "./static")e.GET("/", controller.Index)e.GET("/ws", ws.InitWebSocket)e.Run("0.0.0.0:8080")
}
3、运行测试
浏览器请求 http://localhost:8080/

4、添加session
添加session用来存储在线用户
这里使用一个map用来保存,key是用户id,value是websocket连接,再加一个读写锁保证线程安全
package wsimport ("fmt""github.com/gin-gonic/gin""github.com/gorilla/websocket""log""net/http""sync"
)var connects = make(map[string]*websocket.Conn)
var lock sync.RWMutexfunc addSession(id string, conn *websocket.Conn) {lock.Lock()connects[id] = conndefer lock.Unlock()
}
func getSession(id string) *websocket.Conn {lock.RLock()defer lock.RUnlock()return connects[id]
}
func removeSession(id string) {lock.Lock()delete(connects, id)defer lock.Unlock()
}func InitWebSocket(c *gin.Context) {var upgrader = websocket.Upgrader{ReadBufferSize: 1024,WriteBufferSize: 1024,CheckOrigin: func(r *http.Request) bool {log.Println("升级协议", r.Header["User-Agent"])return true},}conn, err := upgrader.Upgrade(c.Writer, c.Request, nil)if err != nil {log.Println(err)return}defer conn.Close()userId := c.Query("id")log.Println("用户id:", userId)//添加sessionaddSession(userId, conn)for {mt, message, err := conn.ReadMessage()log.Println("获取客户端发送的消息:" + string(message))fmt.Println(mt)if err != nil {log.Println(err)break}var msg = "春风得意马蹄疾,一日看尽长安花"err2 := conn.WriteMessage(websocket.TextMessage, []byte(msg))if err2 != nil {log.Println("write:", err2)break}}}
至此完
相关文章:
golang Gin实现websocket
golang使用 Gin实现 websocket,这里笔者重新搭建一个项目 1、创建项目安装依赖 项目名为 go-gin-websocket 在指定文件夹下,新建项目文件夹 go-gin-websocket 进入项目文件夹,打开cmd窗口,在项目(go-gin-websocket&a…...
冯·诺依曼体系结构与初始操作系统
目录 冯诺依曼体系结构 冯诺依曼体系结构图 内存 外存 网卡和磁盘 结构之间运算速度的差异 缓冲区 初始操作系统 概念 操作系统上边与下边分别有什么 从上到下依次顺序解析 用户 用户操作接口 系统调用接口 操作系统四项管理 驱动 硬件 冯诺依曼体系结构 冯诺…...
软件测试之黑盒测试的具体方法详解
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一.基于需求的设计方法二.等价类三.边界值四.判定表4.1 **关系**4.2 如何设计测试用例4.3 实际案例第一步第二步第三步第四步 五.正交排列5.1 什么是正交表5.2 …...
图形编辑器:历史记录设计
大家好,我是前端西瓜哥。今天讲一下图形编辑器如何实现历史记录,做到撤销重做。 其实就是版本号的更替。每个版本保存一个状态。 数据结构 要记录图形编辑器的历史记录,支持撤销重做功能,需要两个栈:撤销࿰…...
ubuntu22.04下挂载第二块硬盘
文章目录 一、查看硬盘情况二、找到nvme1n1三、挂载四、修改分区文件 一、查看硬盘情况 首先要查看一下系统识别出来的设备。也就是说,我希望知道,ubuntu到底发现了几块硬盘。用命令:lsblk 显示结果如下: 有两块硬盘:…...
举例说明.net中in与out的作用与区别
-----作用 在 .NET 中,in 和 out 是用于泛型类型参数的修饰符,它们用于指定参数类型的协变性和逆变性。 - in 修饰符:表示这个泛型类型参数是协变的。也就是说,in 类型参数可以从较特殊的类型隐式转换为较通用的类型。例如&…...
Java常见的100道面试题(内附答案及代码示例)持续更新
什么是Java程序? Java程序是一组可执行的代码,由Java编译器编译生成,可以在Java虚拟机(JVM)上运行。 public class HelloWorld {public static void main(String[] args) {System.out.println("Hello, World!&qu…...
策略设计模式知多少
目录 目标 概述 实现 目标 熟悉策略设计模式,了解策略设计模式的使用场景、具体实现。 概述 一、行为设计模式 行为设计模式是设计模式的一种类型。该类型的设计模式关注的重点在于对象的行为(通信和交互),而非对象的创建方…...
第三十九章 配置镜像 - 配置 ISCAgent - 在 UNIX Linux 和 macOS 系统上为非根实例启动 ISCAgent
文章目录 第三十九章 配置镜像 - 配置 ISCAgent - 在 UNIX Linux 和 macOS 系统上为非根实例启动 ISCAgent在 UNIX/Linux 和 macOS 系统上为非根实例启动 ISCAgent在 Microsoft Windows 系统上启动 ISCAgent 自定义 ISCAgent 第三十九章 配置镜像 - 配置 ISCAgent - 在 UNIX Li…...
嵌入式安卓开发:使用Camera2获取相机
文章目录 Camera2介绍Camera2的主要API类介绍CameraManager通过CameraManage获取Cameracharacteristics通过CameraManage获取CameraDevice从CameraDevice获取CameraCaptureSession预览效果 参考 Camera2介绍 从Android 5.0开始,Google 引入了一套全新的相机框架 Ca…...
阿里云g8i服务器Intel Xeon(Sapphire Rapids) Platinum 8475B
阿里云服务器ECS通用型实例规格族g8i采用2.7 GHz主频的Intel Xeon(Sapphire Rapids) Platinum 8475B处理器,3.2 GHz睿频,g8i实例采用阿里云全新CIPU架构,可提供稳定的算力输出、更强劲的I/O引擎以及芯片级的安全加固。阿里云百科分享阿里云服…...
设计模式——组件协作模式之观察者模式
文章目录 前言一、“组件协作” 模式二、Observer 观察者模式1、动机2、模式定义3、伪代码示例①、第一种方案,最朴素的方式②、第二种方案,重构使得遵循DIP原则:③、进一步的小优化:④、修改使得支持多个观察者: 4、结…...
观察者设计模式知多少
目录 目标 概述 实现 推设计模式 拉设计模式 被动观察者设计模式 目标 熟悉观察者设计模式,了解观察者设计模式的使用场景、具体实现(包括:推设计模式、拉设计模式、被动观察者设计模式)。 概述 一、行为设计模式 行为设…...
Flink之TaskManager内存解析
一、CK失败 Flink任务的checkpoint操作失败大致分为两种情况,ck decline和ck expire: (1)ck decline 发生ck decline情况时,我们可以通过查看JobManager.log或TaskManager.log查明具体原因。其中有一种特殊情况为ck cancel&…...
为何越来越多人不喜欢“试用期六个月”的公司?网友:感觉不靠谱
众所周知,任何一份工作都有试用期,一般是三月左右。但如果你遇到试用期达到半年的公司,你会不会进入? 近日,就有人遇到了此类公司,并对是否要进入该公司犹豫不决。他在论坛上发帖求助:大家是怎…...
单例模式的四种创建方式
前言 单例模式是日常开发中最常见的一种设计模式,常用来做为池对象,或者计数器之类的需要保证全局唯一的场景。 单例模式的目的是保证在整个程序中只存在一个对象实例,使用单例一个前提条件就是构造器私有化,不允许通过new 对象…...
Nginx+Keepalived 中的脑裂现象
如何解决和预防 NginxKeepalived 中会出现的脑裂现象? Nginx是一种高性能的Web服务器和反向代理服务器,可以处理大量并发请求。Keepalived是一种开源软件,用于实现IP负载均衡和故障转移。在Nginx和Keepalived结合使用时,可以通过将多个Ngin…...
04 KVM虚拟化网络概述
文章目录 04 KVM虚拟化网络概述4.1 Linux Bridge4.2 Open vSwitch 04 KVM虚拟化网络概述 为了使虚拟机可以与外部进行网络通信,需要为虚拟机配置网络环境。KVM虚拟化支持Linux Bridge、Open vSwitch网桥等多种类型的网桥。如图1所示,数据传输路径为“虚…...
110页智慧农业解决方案(农业信息化解决方案)(ppt可编辑)
本资料来源公开网络,仅供个人学习,请勿商用,如有侵权请联系删除。 第一部分 智慧农业概述 智慧农业以农业资源为基础、市场为导向、效益为中心、产业化为抓手,面向农业管理部门、农技推广部门、农业企业、农业园区和基地、农业专…...
Java知识体系及聊天室程序
Java知识体系结构梳理如下: 基础语法:Java的基本语法,包括数据类型、运算符、控制语句、数组等。 面向对象编程:Java是一种面向对象的编程语言,需要掌握类、对象、继承、多态等概念。 异常处理:Java提供了…...
CTF show Web 红包题第六弹
提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框,很难让人不联想到SQL注入,但提示都说了不是SQL注入,所以就不往这方面想了 先查看一下网页源码,发现一段JavaScript代码,有一个关键类ctfs…...
反向工程与模型迁移:打造未来商品详情API的可持续创新体系
在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...
Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
Leetcode 3577. Count the Number of Computer Unlocking Permutations
Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接:3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯,要想要能够将所有的电脑解锁&#x…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...
linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
css的定位(position)详解:相对定位 绝对定位 固定定位
在 CSS 中,元素的定位通过 position 属性控制,共有 5 种定位模式:static(静态定位)、relative(相对定位)、absolute(绝对定位)、fixed(固定定位)和…...
分布式增量爬虫实现方案
之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面,避免重复抓取,以节省资源和时间。 在分布式环境下,增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路:将增量判…...
HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...
论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing
Muffin 论文 现有方法 CRADLE 和 LEMON,依赖模型推理阶段输出进行差分测试,但在训练阶段是不可行的,因为训练阶段直到最后才有固定输出,中间过程是不断变化的。API 库覆盖低,因为各个 API 都是在各种具体场景下使用。…...
