青少年编程与数学 02-004 Go语言Web编程 07课题、WebSockets

embedded/2024/12/23 18:07:57/

青少年编程与数学 02-004 Go语言Web编程 07课题、WebSockets

  • 一、WebSockets
      • WebSockets 的特点:
      • WebSockets 的工作流程:
      • WebSockets 的应用场景:
  • 二、Go Web应用中使用WebSockets
      • 1. 使用`gorilla/websocket`库
      • 2. 使用`net/http`包
      • 3. 其他库
  • 三、示例应用
      • 步骤 1: 安装依赖
      • 步骤 2: 创建WebSocket服务器
      • 步骤 3: 运行服务器
      • 步骤 4: 创建客户端

课题摘要:本文介绍了WebSockets的概念、特点、工作流程和应用场景,并探讨了在Go Web应用中如何使用WebSockets。WebSockets是一种网络通信协议,支持全双工通信和持久连接,适用于实时应用。工作流程包括握手、服务器响应、连接建立、数据传输和连接关闭。应用场景包括实时聊天、在线游戏、实时数据更新等。在Go中,可以使用gorilla/websocket库或net/http包实现WebSockets,其中gorilla/websocket提供了丰富的功能。文章还提供了一个使用gorilla/websocket库的示例应用,展示了服务器和客户端之间的实时消息交换。通过这些方法,可以在Go Web应用中实现WebSockets,增加实时通信功能。


一、WebSockets

WebSockets 是一种网络通信协议,提供了在单个TCP连接上进行全双工通信的能力。它是HTML5的一部分,并且被设计为在Web页面和服务器之间建立一个持久的连接,允许服务器主动向客户端发送消息,同时也允许客户端向服务器发送消息。

WebSockets 的特点:

  1. 全双工通信

    • WebSockets 允许服务器和客户端之间进行双向实时通信,这意味着双方可以随时向对方发送数据,不需要等待请求。
  2. 持久连接

    • 一旦WebSocket连接建立,它会保持开放状态,直到客户端或服务器决定关闭连接。
  3. 基于HTTP的握手

    • WebSocket连接的建立是通过一个HTTP请求完成的,这个请求包含了特定的头部信息,用于升级到WebSocket协议。
  4. 适用于实时应用

    • WebSockets非常适合需要实时数据传输的应用,如在线游戏、实时聊天应用、股票行情更新等。
  5. 减少开销

    • 与HTTP相比,WebSockets在数据传输时不需要每次都发送请求头,这减少了数据传输的开销。
  6. 跨域通信

    • WebSockets支持跨域通信,但需要服务器配置适当的CORS(跨源资源共享)策略。

WebSockets 的工作流程:

  1. 握手

    • 客户端通过发送一个特殊的HTTP请求来发起WebSocket连接,这个请求包含了Upgrade头部,表明它想要升级到WebSocket协议。
  2. 服务器响应

    • 如果服务器同意升级,它会发送一个HTTP响应,同样包含Upgrade头部,并包含一个唯一的Sec-WebSocket-Accept值。
  3. 连接建立

    • 一旦握手成功,客户端和服务器之间的连接就转变为WebSocket连接,双方可以开始通过这个连接发送数据。
  4. 数据传输

    • 数据可以通过这个连接发送,WebSocket协议定义了如何格式化和传输这些数据。
  5. 连接关闭

    • 任何一方都可以通过发送一个关闭帧来关闭WebSocket连接。

WebSockets 的应用场景:

  • 实时聊天应用:如即时通讯软件、在线客服系统。
  • 在线游戏:需要实时交互的游戏。
  • 实时数据更新:如股票价格更新、新闻推送。
  • 协作工具:如在线文档编辑、设计工具。
  • 物联网(IoT):设备状态的实时监控和控制。

WebSockets 通过提供一种在Web浏览器和服务器之间进行实时、双向通信的机制,极大地扩展了Web应用的功能和可能性。

二、Go Web应用中使用WebSockets

在Go Web应用中使用WebSockets,你可以选择多种方法和库来实现。以下是几种流行的方法:

1. 使用gorilla/websocket

gorilla/websocket是Go中实现WebSockets的一个非常流行的库。以下是如何使用这个库的基本步骤:

安装依赖

go get github.com/gorilla/websocket

实现WebSocket处理器
pkg/websocket/websocket.go中实现WebSocket处理器:

package websocketimport ("net/http""sync""github.com/gorilla/websocket""github.com/zeromicro/go-zero/core/logx"
)var upgrader = websocket.Upgrader{CheckOrigin: func(r *http.Request) bool {return true // 允许所有来源,您可能需要根据实际情况修改这个检查},
}type Connection struct {conn *websocket.Connmu   sync.Mutex
}type Hub struct {connections map[*Connection]boolbroadcast   chan []byteregister    chan *Connectionunregister  chan *Connection
}func NewHub() *Hub {return &Hub{connections: make(map[*Connection]bool),broadcast:   make(chan []byte),register:    make(chan *Connection),unregister:  make(chan *Connection),}
}func (h *Hub) Run() {for {select {case conn := <-h.register:h.connections[conn] = truecase conn := <-h.unregister:if _, ok := h.connections[conn]; ok {delete(h.connections, conn)conn.conn.Close()}case message := <-h.broadcast:for conn := range h.connections {conn.Write(message)}}}
}func (c *Connection) Write(message []byte) {c.mu.Lock()defer c.mu.Unlock()err := c.conn.WriteMessage(websocket.TextMessage, message)if err != nil {logx.Errorf("Error writing message: %v", err)}
}func (h *Hub) HandleWebSocket(w http.ResponseWriter, r *http.Request) {conn, err := upgrader.Upgrade(w, r, nil)if err != nil {logx.Errorf("Error upgrading to WebSocket: %v", err)return}c := &Connection{conn: conn}h.register <- cdefer func() {h.unregister <- c}()for {_, message, err := conn.ReadMessage()if err != nil {if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure) {logx.Errorf("Error reading message: %v", err)}break}h.broadcast <- message}
}

这段代码定义了一个WebSocket处理器,用于处理WebSocket连接和消息传递。

2. 使用net/http

Go语言的net/http包也可以用来实现WebSockets,尽管它不像gorilla/websocket那样功能丰富。以下是基本的步骤:

创建WebSocket服务器

import ("github.com/gorilla/websocket""net/http"
)var upgrader = websocket.Upgrader{ReadBufferSize:  1024,WriteBufferSize: 1024,
}func wsHandler(w http.ResponseWriter, r *http.Request) {conn, err := upgrader.Upgrade(w, r, nil)if err != nil {// 处理错误}defer conn.Close()for {messageType, p, err := conn.ReadMessage()if err != nil {// 处理错误}// 处理接收到的消息err = conn.WriteMessage(messageType, p)if err != nil {// 处理错误}}
}func main() {http.HandleFunc("/ws", wsHandler)log.Fatal(http.ListenAndServe(":8080", nil))
}

在这个例子中,我们创建了一个WebSocket升级器upgrader,并在wsHandler函数中使用它来升级HTTP连接为WebSocket连接。然后,我们使用一个无限循环来读取和写入消息。

3. 其他库

除了gorilla/websocketnet/http包,还有其他几个库可以用来实现WebSockets,例如gobwas/wsgowebsocket。这些库提供了不同的功能和特点,你可以根据项目需求选择适合的库。

通过这些方法,你可以在Go Web应用中实现WebSockets,为应用添加实时通信功能。

三、示例应用

下面是一个简单的Go Web应用示例,它使用gorilla/websocket库来实现WebSockets,并展示双工通信和持久连接的特性。这个应用将允许客户端和服务器之间进行实时的消息交换。

步骤 1: 安装依赖

首先,你需要安装gorilla/websocket库:

go get github.com/gorilla/websocket

步骤 2: 创建WebSocket服务器

创建一个文件main.go,并添加以下代码:

package mainimport ("log""net/http""github.com/gorilla/websocket"
)var upgrader = websocket.Upgrader{ReadBufferSize:  1024,WriteBufferSize: 1024,CheckOrigin: func(r *http.Request) bool {return true},
}// connection 代表一个WebSocket连接
type connection struct {conn *websocket.Connsend chan []byte
}var connections = make(map[*connection]bool)// broadcast 广播消息给所有连接的客户端
func broadcast(message []byte) {for c := range connections {select {case c.send <- message:default:close(c.conn)delete(connections, c)}}
}// readPump 从WebSocket读取消息并广播
func (c *connection) readPump() {defer func() {close(c.send)c.conn.Close()delete(connections, c)}()for {_, message, err := c.conn.ReadMessage()if err != nil {return}broadcast(message)}
}// writePump 向WebSocket发送消息
func (c *connection) writePump() {defer c.conn.Close()for message := range c.send {if err := c.conn.WriteMessage(websocket.TextMessage, message); err != nil {return}}
}func handleConnections(w http.ResponseWriter, r *http.Request) {conn, err := upgrader.Upgrade(w, r, nil)if err != nil {log.Println(err)return}c := &connection{conn: conn, send: make(chan []byte, 256)}connections[c] = truego c.writePump()c.readPump()
}func main() {http.HandleFunc("/ws", handleConnections)log.Fatal(http.ListenAndServe(":8080", nil))
}

步骤 3: 运行服务器

运行main.go文件:

go run main.go

服务器将在8080端口上监听WebSocket连接。

步骤 4: 创建客户端

你可以使用JavaScript创建一个简单的客户端来连接到这个WebSocket服务器,并发送和接收消息。在HTML文件中添加以下代码:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>WebSocket Test</title><script>var ws = new WebSocket("ws://localhost:8080/ws");ws.onopen = function() {console.log("Connected to the WebSocket server.");};ws.onmessage = function(event) {console.log("Message from server: ", event.data);// Send a message back to the serverws.send("Pong: " + event.data);};ws.onclose = function(event) {console.log("Disconnected from the WebSocket server.");};ws.onerror = function(error) {console.log("WebSocket error observed:", error);};</script>
</head>
<body><h1>WebSocket Test</h1>
</body>
</html>

将这段代码保存为index.html,并在浏览器中打开它。你将在浏览器的控制台中看到客户端和服务器之间的通信。

这个简单的应用展示了WebSocket的双工通信和持久连接特性。服务器可以向所有连接的客户端广播消息,客户端也可以向服务器发送消息。这种模式适用于需要实时通信的应用,如聊天应用、实时游戏等。


http://www.ppmy.cn/embedded/148131.html

相关文章

【Mybatis-Plus】连表查询 逻辑删除 多租户

文章目录 连表查询逻辑删除多租户 连表查询 引入 mybatis-plus-join-boot-starter 依赖 <dependency><groupId>com.github.yulichang</groupId><artifactId>mybatis-plus-join-boot-starter</artifactId><version>1.5.1</version>…

Deepin/Linux clash TUN模式不起作用,因网关导致的问题的解决方案。

网关导致的问题的解决方案 查看路由 ip route寻找默认路由 默认路由应当为Mihomo default dev Mihomo scope link 如果不是&#xff0c;则 sudo ip route add default dev Mihomo在clash TUN开关状态发生变化时&#xff0c;Mihomo网卡会消失&#xff0c;所以提示找不到网卡…

【活动邀请·深圳】深圳COC社区 深圳 AWS UG 2024 re:Invent re:Cap

re:Invent 是全球云计算领域的顶级盛会&#xff0c;每年都会吸引来自世界各地的技术领袖、创新者和实践者汇聚一堂&#xff0c;分享最新的技术成果和创新实践&#xff0c;深圳 UG 作为亚马逊云科技技术社区的重要组成部分&#xff0c;将借助 re:Invent 的东风&#xff0c;举办此…

C# Redis分布式锁

使用包StackExchange.Redis&#xff0c;可以在NuGet中下载到 可以支持多并发请求&#xff0c;保持数据一致性和不重复已经保证代码只再一次请求结束后再执行 public static async Task<bool> TryAcquireLockAsync() {bool isAcquired false;while (!isAcquired){isAcq…

fastAPI接口的请求与响应——基础

1. 后端接口 1.接口实现 pip install fastapi pip install uvicorn# api.py from pydantic import BaseModel from fastapi import FastAPI import uvicorn import os# 定义请求体模型 class Payload(BaseModel):key1: strkey2: str# 创建一个FastAPI应用程序实例 app Fast…

【数据结构】平衡二叉树

目录 一、概念 二、平衡二叉树的插入 &#xff08;一&#xff09;插入步骤 &#xff08;二&#xff09;旋转 1、左旋 2、右旋 3、左右双旋 4、右左双旋 三、特点 四、整体代码 一、概念 平衡二叉树是在二叉搜索树的改进&#xff0c;二叉搜索树详见&#xff1a;【数据结…

Linux系统加固

Linux系统安全加固 文章目录 Linux系统安全加固密码策略文件、目录安全未授权suid、未授权sgid排查与加固禁止root登录ftp、禁止匿名访问ftp计划任务排查与加固、开机自启排查与加固限定root用户远程ssh登录日志加固 无用账号、用户组和空口令账户排查与加固 禁用或删除无用账号…

【mysql】1205 -Lock wait timeout exceeded; try restarting transaction

问题&#xff1a; mysql8执行SQL提示下面错误&#xff1a; 1205 -Lock wait timeout exceeded; try restarting transaction 1205-超过锁定等待超时&#xff1b;尝试重新启动事务 可能的原因&#xff1a; 事务冲突&#xff1a;多个事务同时尝试修改同一行数据&#xff0c;导…