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连接中读取服务器的响应消息,如果读取失败,将打印错误。最后,打印从服务器接收到的消息。
请登录后再评论