15分钟学 Go 实战项目三 : 实时聊天室(学习WebSocket并发处理)
实时聊天室:学习WebSocket并发处理
目标概述
在本项目中,我们将创建一个实时聊天室,使用Go语言和WebSocket来处理并发消息交流。这将帮助你深入理解WebSocket协议的工作原理以及如何在Go中实现并发处理。
1. 项目需求
功能需求
- 用户可以通过浏览器连接到聊天室。
- 用户能发送和接收消息。
- 支持多个用户同时在线聊天。
- 提供简单的用户界面,展示消息。
技术需求
- Go语言: 用于后端服务器开发。
- Gorilla WebSocket: Go语言实现的WebSocket库。
- HTML/CSS/JavaScript: 用于前端界面开发。
2. 学习WebSocket
2.1 WebSocket概述
WebSocket是一种协议,允许在客户端和服务器之间建立持久性的全双工通信通道。它非常适合实时应用,如聊天应用、实时通知等。
WebSocket的优点
- 全双工通信:客户端和服务器可以随时互相发送数据。
- 低延迟:与HTTP相比,WebSocket在数据传输时会有更低的延迟。
- 节省资源:WebSocket连接在建立后可以保持打开状态,避免重复连接。
2.2 WebSocket协议工作流
WebSocket的建立过程如下:
- 客户端发送HTTP请求升级连接至WebSocket。
- 服务器确认并完成连接协议升级。
- 完成后,双方可以开始进行实时数据传输。
3. 项目结构
3.1 项目目录
chatroom/
├── main.go
├── index.html
└── styles.css
3.2 各文件功能
- main.go: 服务器的主逻辑。
- index.html: 客户端聊天界面。
- styles.css: 界面的样式定义。
4. 代码实现
4.1 main.go - 服务器端实现
下面是主要的Go代码实现,包含WebSocket处理和并发支持:
package mainimport ("fmt""net/http""sync""github.com/gorilla/websocket"
)var upgrader = websocket.Upgrader{CheckOrigin: func(r *http.Request) bool {return true},
}type Client struct {conn *websocket.Connsend chan []byte
}type Hub struct {clients map[*Client]boolbroadcast chan []bytemutex sync.Mutex
}var hub = Hub{clients: make(map[*Client]bool),broadcast: make(chan []byte),
}func (h *Hub) run() {for {msg := <-h.broadcasth.mutex.Lock()for client := range h.clients {select {case client.send <- msg:default:close(client.send)delete(h.clients, client)}}h.mutex.Unlock()}
}func (c *Client) read() {defer func() {hub.mutex.Lock()delete(hub.clients, c)hub.mutex.Unlock()c.conn.Close()}()for {_, msg, err := c.conn.ReadMessage()if err != nil {break}hub.broadcast <- msg}
}func (c *Client) write() {defer c.conn.Close()for msg := range c.send {if err := c.conn.WriteMessage(websocket.TextMessage, msg); err != nil {break}}
}func handleConnection(w http.ResponseWriter, r *http.Request) {conn, err := upgrader.Upgrade(w, r, nil)if err != nil {fmt.Println(err)return}client := &Client{conn: conn, send: make(chan []byte)}hub.mutex.Lock()hub.clients[client] = truehub.mutex.Unlock()go client.write()client.read()
}func main() {go hub.run()http.HandleFunc("/ws", handleConnection)http.Handle("/", http.FileServer(http.Dir("./")))fmt.Println("Server started at :8080")if err := http.ListenAndServe(":8080", nil); err != nil {fmt.Println("Error while starting the server:", err)}
}
4.2 index.html - 客户端实现
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Chat Room</title><link rel="stylesheet" href="styles.css">
</head>
<body><div id="chat-container"><div id="messages"></div><input id="message-input" type="text" placeholder="Type a message..." autocomplete="off" /><button id="send-button">Send</button></div><script>const messages = document.getElementById('messages');const input = document.getElementById('message-input');const sendButton = document.getElementById('send-button');const connection = new WebSocket('ws://' + window.location.host + '/ws');connection.onmessage = function(event) {const messageElement = document.createElement('div');messageElement.textContent = event.data;messages.appendChild(messageElement);};sendButton.onclick = function() {const message = input.value;if (message) {connection.send(message);input.value = '';}};</script>
</body>
</html>
4.3 styles.css - 样式定义
body {font-family: Arial, sans-serif;
}#chat-container {width: 600px;margin: 0 auto;border: 1px solid #ccc;padding: 10px;
}#messages {height: 400px;overflow-y: scroll;border: 1px solid #ccc;margin-bottom: 10px;
}#message-input {width: 80%;padding: 10px;
}#send-button {padding: 10px;
}
5. 代码运行流程图
+-------------------+
| Start Server |
| (main.go) |
+---------+---------+|v
+-------------------+
| Handle |
| WebSocket |<--------------------+
| Connection | |
+---------+---------+ || |v |
+---------+---------+ |
| Create Client | |
+---------+---------+ || |v |
+---------+---------+ |
| Read Message | |
+---------+---------+ || |+--------------------->---------+|v+----------+-----------+| Broadcast Message |+----------+-----------+|v+----------+-----------+| Send Message to All |+----------------------+
6. 运行项目
6.1 运行步骤
- 确保Go环境已经安装,并且你的工作目录在
chatroom。 - 安装Gorilla WebSocket库:
go get -u github.com/gorilla/websocket
- 在项目目录下运行服务器:
go run main.go
- 在浏览器中访问
http://localhost:8080来使用聊天室。
6.2 测试聊天室
你可以在多个浏览器窗口中打开同一地址,发送消息以查看所有连接的用户是否可以实时收到消息。这将帮助你理解并发处理和WebSocket的使用。
7. 总结与扩展
7.1 项目总结
通过这个项目,你学习了如何使用Go语言创建一个支持WebSocket的实时聊天室。了解了WebSocket的工作原理,并掌握了Go中的并发处理方法,为以后的项目开发打下了基础。
7.2 可能的扩展功能
- 用户身份验证:支持用户注册和登录功能。
- 消息历史记录:将聊天记录存储到数据库。
- 聊天室管理:允许用户创建和管理多个聊天室。
- 客户端样式优化:提升用户界面的美观度和用户体验。
8. 参考资料
- Go Documentation
- Gorilla WebSocket
- WebSocket Protocol
怎么样今天的内容还满意吗?再次感谢观众老爷的观看,关注GZH:凡人的AI工具箱,回复666,送您价值199的AI大礼包。最后,祝您早日实现财务自由,还请给个赞,谢谢!
相关文章:
15分钟学 Go 实战项目三 : 实时聊天室(学习WebSocket并发处理)
实时聊天室:学习WebSocket并发处理 目标概述 在本项目中,我们将创建一个实时聊天室,使用Go语言和WebSocket来处理并发消息交流。这将帮助你深入理解WebSocket协议的工作原理以及如何在Go中实现并发处理。 1. 项目需求 功能需求 用户可以…...
架构评估的方法
三种评估方法※ 第一是基于问卷(检查表)的方式,通过问卷调查对系统比较熟悉的相关人员,这种方式主观性很强。 专家问卷评估、用户问卷评估、内部团队问卷评估 第二是基于度量的方式,对系统指标完全量化,基于量化指标评价系统,这种方式需要评估者对系统非常熟悉。 软件质…...
羲和数据集收集器1.0
为了提升问答对的提取能力并完善GUI,我们从以下几个方面进行改进: 增强文本清理和解析能力:确保能够更准确地识别问答对。 支持更多文件格式:除了现有的 .txt, .docx, 和 .pdf,可以考虑支持其他常见格式如 .xlsx 等。 优化GUI设计:提供更友好的用户界面,包括进度条、日…...
ENSP OSPF和BGP引入
路由协议分为:内部网关协议和外部网关协议。内部网关协议用于自治系统内部的路由,包括:RIP和OSPF。外部网关协议用于自治系统之间的路由,包括BGP。内部网关协议和外部网关协议配合来共同完成网络的路由。 BGP:边界网关路由协议(b…...
软件工程 软考
开发大型软件系统适用螺旋模型或者RUP模型 螺旋模型强调了风险分析,特别适用于庞大而复杂的、高风险的管理信息系统的开发。喷泉模型是一种以用户需求为动力,以对象为为驱动的模型,主要用于描述面向对象的软件开发过程。该模型的各个阶段没有…...
证书学习(六)TSA 时间戳服务器原理 + 7 个免费时间戳服务器地址
目录 一、简介1.1 什么是时间戳服务器1.2 名词扩展1.3 用时间戳标记顺序1.4 7 个免费TSA时间戳服务器地址(亲测可用)1.5 RFC 3161 标准二、时间戳原理2.1 时间戳服务工作流程2.2 验证工作流程2.3 举个例子2.4 时间戳原理总结三、代码实现3.1 curl 命令请求时间戳3.2 java 代码…...
NVR设备ONVIF接入平台EasyCVR私有化部署视频平台如何安装欧拉OpenEuler 20.3 MySQL
在当今数字化时代,安防视频监控系统已成为保障公共安全和个人财产安全的重要工具。NVR设备ONVIF接入平台EasyCVR作为一款功能强大的智能视频监控管理平台,它不仅提供了视频远程监控、录像、存储与回放等基础功能,还涵盖了视频转码、视频快照、…...
c中柔性数组
c99中,结构中最后一个元素允许是未知大小的数组,这就叫柔性数组成员。 柔性数组的特点 1.结构中柔性数组前必须至少有一个其他成员 2.sizeof返回的这种结构大小不包括柔性数组的内存 3.包含柔性数组成员的结构用malloc函数进行动态分配,并…...
图像信号处理器(ISP,Image Signal Processor)详解
简介:个人学习分享,如有错误,欢迎批评指正。 图像信号处理器(ISP,Image Signal Processor) 是专门用于处理图像信号的硬件或处理单元,广泛应用于图像传感器(如 CMOS 或 CCD 传感器&a…...
越权访问漏洞
V2Board Admin.php 越权访问漏洞 ## 漏洞描述 V2board面板 Admin.php 存在越权访问漏洞,由于部分鉴权代码于v1.6.1版本进行了修改,鉴权方式变为从Redis中获取缓存判定是否存在可以调用… V2Board Admin.php 越权访问漏洞 漏洞描述 V2board面板 Admin.ph…...
【Ant.designpro】上传图片
文章目录 一、前端二、后端 一、前端 fieldProps:可以监听并且获取到组件输入的内容 action{“/api/upload_image”} 直接调用后端接口 <ProFormUploadButtonlabel{"上传手续图片"}name{"imgs"}action{"/api/upload_image"}max{5} fieldPro…...
为何选择Spring AI Alibaba开发智能客服平台?
0 前言 本文来看如何使用Spring AI Alibaba构建Agent应用。 1 需求 智能客服平台,可帮助用户完成机票预定、问题解答、机票改签、取消等动作,具体要求: 基于 AI 大模型与用户对话,理解用户自然语言表达的需求支持多轮连续对话…...
HiveSQL 中判断字段是否包含某个值的方法
HiveSQL 中判断字段是否包含某个值的方法 在 HiveSQL 中,有时我们需要判断一个字段是否包含某个特定的值。下面将介绍几种常用的方法来实现这个功能。 一、创建示例表并插入数据 首先,我们创建一个名为employee的表,并插入一些示例数据&am…...
Nginx简易配置将内网网站ssh转发到外网
声明:本内容仅供交流学习使用,部署网站上线还需要根据有关规定申请域名以及备案。 背景 在内网的服务器有一个运行的网页,现使用ssh反向代理,将它转发到外网的服务器。 但是外网的访问ip会被ssh反向代理拦截 所以使用Nginx进行…...
【go从零单排】error错误处理及封装
🌈Don’t worry , just coding! 内耗与overthinking只会削弱你的精力,虚度你的光阴,每天迈出一小步,回头时发现已经走了很远。 📗概念 在 Go 语言中,error 是一个内置的接口类型,用于表示错误情…...
全平台设置jetbrains mono字体
相信大家都用过IDEA,推荐使用开发字体:jetbrains mono 本地下载的位置(记一下)后续需要打开安装 本地下载的:E:\download\font\jetbrainsmono\JetBrainsMono-2.304\fonts\ttf 官网上下载:https://www.jetbr…...
高校体育场管理系统+ssm
摘 要 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,高校体育场管理系统被用户普遍使用,为方便用户…...
Python学习从0到1 day27 第三阶段 Spark ② 数据计算Ⅰ
人总是会执着于失去的,而又不珍惜现在所拥有的 —— 24.11.9 一、map方法 PySpark的数据计算,都是基于RDD对象来进行的,采用依赖进行,RDD对象内置丰富的成员方法(算子) map算子 功能:map算子…...
Python学习从0到1 day27 第三阶段 Spark ③ 数据计算 Ⅱ
目录 一、Filter方法 功能 语法 代码 总结 filter算子 二、distinct方法 功能 语法 代码 总结 distinct算子 三、SortBy方法 功能 语法 代码 总结 sortBy算子 四、数据计算练习 需求: 解答 总结 去重函数: 过滤函数: 转换函数: 排…...
腾讯混元3D模型Hunyuan3D-1.0部署与推理优化指南
腾讯混元3D模型Hunyuan3D-1.0部署与推理优化指南 摘要: 本文将详细介绍如何部署腾讯混元3D模型Hunyuan3D-1.0,并针对不同硬件配置提供优化的推理方案。我们将探讨如何在有限的GPU内存下,通过调整配置来优化模型的推理性能。 1. 项目概览 腾…...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...
边缘计算医疗风险自查APP开发方案
核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...
云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...
深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法
深入浅出:JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中,随机数的生成看似简单,却隐藏着许多玄机。无论是生成密码、加密密钥,还是创建安全令牌,随机数的质量直接关系到系统的安全性。Jav…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...
12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...
微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...
学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...
Android第十三次面试总结(四大 组件基础)
Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机: onCreate() 调用时机:Activity 首次创建时调用。…...
