47、Go语言基础 - 网络编程 - WebSocket 服务

作者: 温新

分类: 【Go基础】

阅读: 291

时间: 2023-12-05 00:39:32

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