这段时间工作需求用到实现双工通信,因此选择WebSocket来开发,简单记录一下。
1.安装WebSocket
在 Go 语言中操作 WebSocket 可以通过使用 gorilla/websocket 包来实现。
go get github.com/gorilla/websocket
2.服务端代码
// Upgrader 用于升级 HTTP 连接到 WebSocket 连接
var upgrader = websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool {
return true // 允许所有来源的连接,生产环境应进行适当的来源验证
},
}
// WebSocketHandler 处理 WebSocket 连接
func WebSocketHandler(c *gin.Context) {
conn, err := upgrader.Upgrade(c.Writer, c.Request, nil)
if err != nil {
fmt.Println("Upgrade error:", err)
return
}
defer conn.Close()
for {
// 读取消息
messageType, message, err := conn.ReadMessage()
if err != nil {
fmt.Println("Read error:", err)
break
}
fmt.Printf("Received: %s\n", message)
// 回显消息
err = conn.WriteMessage(messageType, message)
if err != nil {
fmt.Println("Write error:", err)
break
}
}
}
func main() {
router := gin.Default()
// 配置 WebSocket 路由
router.GET("/ws", WebSocketHandler)
fmt.Println("Server started on :8080")
if err := router.Run(":8080"); err != nil {
fmt.Println("Run error:", err)
}
}
在 Upgrader 中还可以指定缓冲区的大小,修改如下:
var upgrader = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
CheckOrigin: func(r *http.Request) bool {
return true
},
}
如果不使用gin使用原生http包开发的话,handler代码如下(主要是函数接收参数的变化):
func handler(w http.ResponseWriter, r *http.Request) {
conn, err := upgrader.Upgrade(w, r, nil)
// 同上
}
3.客户端代码
func main() {
u := url.URL{Scheme: "ws", Host: "localhost:8080", Path: "/ws"}
fmt.Printf("Connecting to %s\n", u.String())
conn, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
if err != nil {
log.Fatal("Dial error:", err)
}
defer conn.Close()
// 发送消息
err = conn.WriteMessage(websocket.TextMessage, []byte("Hello, WebSocket!"))
if err != nil {
log.Fatal("Write error:", err)
}
// 读取消息
_, message, err := conn.ReadMessage()
if err != nil {
log.Fatal("Read error:", err)
}
fmt.Printf("Received: %s\n", message)
}
非必要,可以直接使用 postman 来快速模拟测试。
4.postman模拟测试
新建 request 选择 WebSocket 协议,接着 Connect 上,Send消息
5.开启SSL
在 WebSocket 服务器中配置 SSL(即使用 wss 协议而不是 ws )
5.1生成测试用的自签名证书
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365
这会生成两个文件:key.pem(私钥)和 cert.pem(证书),放到项目的根目录即可。
5.2修改服务端代码
只要修改 router.Run(“:8080”) 为 router.RunTLS(“:8080”, “cert.pem”, “key.pem”)即可
func main() {
router := gin.Default()
// 配置 WebSocket 路由
router.GET("/ws", WebSocketHandler)
fmt.Println("Server started on :8080")
err := router.RunTLS(":8080", "cert.pem", "key.pem")
if err != nil {
fmt.Println("RunTLS error:", err)
}
}
5.3postman测试
只需将 localhost:8080/ws 修改为 wss://localhost:8080/ws 即可。