47、Go语言基础 - 网络编程 - WebSocket 服务
hi,我是温新
什么是 WebSocket
WebSocket是一种在单个TCP连接上进行全双工通信的通信协议。它允许客户端和服务器之间进行双向实时数据传输,而不像HTTP那样需要每次请求都建立新的连接。
主要特点和优势包括:
- 实时性:WebSocket 提供实时性通信,允许服务器主动向客户端推送数据,而无需等待客户端请求。这使得它非常适用于需要实时互动性的应用程序,如在线聊天、在线游戏、股票市场数据更新等。
- 双向通信:WebSocket 允许双向通信,客户端和服务器都可以在同一连接上发送消息,而不必等待对方的请求。
- 低开销:与传统的HTTP请求/响应模型相比,WebSocket 减少了头部开销,因为它使用较少的数据包进行通信。
- 持久连接:WebSocket 连接可以保持打开状态,而不必经历连接建立和断开的开销,这使得它适合于长时间运行的应用程序。
- 协议标准:WebSocke t有一个标准的协议,定义了消息的格式和通信的规则,这使得不同语言和平台的应用程序能够互相通信。
WebSocket 通常用于 Web 应用程序,但也可以在各种应用程序和设备上使用,以提供实时的数据传输和互动性。WebSocket API 在多种编程语言和 Web 框架中都得到了支持,使开发者能够轻松实现 WebSocket 功能。
WebSocket 服务端
使用 websocket 之前,先导入包,如果没有,使用go get github.com/gorilla/websocket 导入包到项目中。
package main
import (
	"fmt"
	"github.com/gorilla/websocket"
	"net/http"
)
// 创建一个 Upgrader,用于将 HTTP 连接升级为 WebSocket 连接
var upgrader = websocket.Upgrader{
	CheckOrigin: func(r *http.Request) bool {
		return true
	},
}
func main() {
	// 将 WebSocket 请求处理函数与路径 /ws 关联
	http.HandleFunc("/ws", handler)
	// 启动 HTTP 服务器,监听端口 8080
	fmt.Println("WebSocket 服务已启动 :8080/ws")
	http.ListenAndServe(":8080", nil)
}
// WebSocket 请求处理函数
func handler(w http.ResponseWriter, r *http.Request) {
	// 将 HTTP 连接升级为 WebSocket 连接
	conn, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		fmt.Println("Error:", err)
		return
	}
    
    // 在函数结束时关闭 WebSocket 连接
	defer conn.Close() 
	for {
		// 从 WebSocket 连接中读取消息
		messageType, p, err := conn.ReadMessage()
		if err != nil {
			return
		}
		fmt.Printf("Received: %s\n", p) // 打印接收到的消息
		// 将接收到的消息写回给客户端
		if err = conn.WriteMessage(messageType, p); err != nil {
			return
		}
	}
}
这个示例创建了一个简单的 WebSocket 服务器,它可以与客户端进行双向通信。
以下是代码解释:
- 引入所需的包和依赖,其中 github.com/gorilla/websocket包用于处理 WebSocket 连接。
- 创建一个 Upgrader变量,它用于将HTTP连接升级为 WebSocket 连接。CheckOrigin函数用于检查 WebSocket 连接的源是否合法,这里简单地返回true,允许所有连接。
- 定义了一个名为 handler的函数,它是WebSocket请求处理函数。这个函数首先尝试将 HTTP 连接升级为 WebSocke t连接,然后在一个无限循环中等待从客户端接收消息。一旦收到消息,它将消息打印到控制台并将相同的消息写回给客户端。
- 在 main函数中,将 WebSocket 请求处理函数与路径"/ws"关联,以便在该路径上处理 WebSocket 连接。
- 最后,使用 http.ListenAndServe启动HTTP服务器,监听端口 8080,并打印一条消息表示 WebSocket 服务器正在运行。
WebSocket 客户端
package main
import (
	"fmt"
	"github.com/gorilla/websocket"
	"log"
)
func main() {
	// WebSocket 服务器的地址
	serverURL := "ws://127.0.0.1:8080/ws"
	// 使用默认的 WebSocket 拨号器 Dialer 创建 WebSocket 连接
	c, _, err := websocket.DefaultDialer.Dial(serverURL, nil)
	if err != nil {
		log.Fatal("Dial error:", err) // 如果连接失败,打印错误并终止程序
	}
	defer c.Close() // 在函数结束时关闭WebSocket连接
	// 准备要发送的消息,这里将其编码为字节数组
	message := []byte("Hello, WebSocket Server!")
	// 使用 WebSocket 连接发送消息,指定消息类型为 TextMessage
	err = c.WriteMessage(websocket.TextMessage, message)
	if err != nil {
		log.Println("Write error:", err) // 如果发送消息失败,打印错误
		return
	}
	// 从WebSocket 连接中读取服务器的响应消息
	_, p, err := c.ReadMessage()
	if err != nil {
		log.Println("Read error:", err) // 如果读取响应消息失败,打印错误
		return
	}
	fmt.Printf("Received from server: %s\n", p) // 打印从服务器接收到的消息
}
这个示例演示了一个简单的 WebSocket 客户端,它连接到 WebSocket 服务器,发送一条消息,然后接收和打印来自服务器的响应消息。
以下是代码解释:
- 引入所需的包,包括github.com/gorilla/websocket用于处理WebSocket连接。
- 定义WebSocket服务器的地址,serverURL是服务器的WebSocket URL。
- 使用websocket.DefaultDialer.Dial创建WebSocket连接。如果连接失败,将打印错误并终止程序。defer c.Close()确保在函数结束时关闭WebSocket连接。
- 准备要发送的消息,这里将消息编码为字节数组。
- 使用WebSocket连接(c)发送消息,指定消息类型为websocket.TextMessage。如果发送消息失败,将打印错误。
- 从WebSocket连接中读取服务器的响应消息,如果读取失败,将打印错误。最后,打印从服务器接收到的消息。
请登录后再评论