在实时应用开发中,我们常需要同时提供 HTTP 接口(用于常规请求)和 WebSocket 服务(用于实时双向通信)。那 Go 语言能否高效兼顾这两者?答案是:完全可以,且实现异常简洁。

Go 原生 net/http 包可直接搭建 HTTP 服务,而 WebSocket 可通过成熟的第三方库实现协议升级,两者能共用一个端口、一个服务实例,无需额外部署,天生适配高并发场景。

核心原理:HTTP 握手升级为 WebSocket

WebSocket 协议的核心是“基于 HTTP 握手升级”——客户端先发送 HTTP 请求,携带 Upgrade: websocket 等头信息,服务端识别后将连接升级为 WebSocket 长连接,之后双方即可双向收发数据。

Go 中借助 gorilla/websocket 库(Go 生态最主流的 WebSocket 实现,稳定且易用)可快速完成升级,同时不影响原有 HTTP 服务的正常运行。

极简实现:一行命令+几十行代码

1. 依赖安装

仅需安装一个第三方库:


go get github.com/gorilla/websocket

2. 完整代码

精简后核心代码(保留双服务核心逻辑,可直接复制运行):


package main

import (
    "log"
    "net/http"
    "github.com/gorilla/websocket"
)

var upgrader = websocket.Upgrader{CheckOrigin: func(r *http.Request) bool { return true }}

func handleWS(w http.ResponseWriter, r *http.Request) {
    conn, err := upgrader.Upgrade(w, r, nil)
    if err != nil { log.Println(err); return }
    defer conn.Close()
    for {
        mt, msg, err := conn.ReadMessage()
        if err != nil { break }
        log.Printf("recv: %s", msg)
        if err := conn.WriteMessage(mt, msg); err != nil { break }
    }
}

func handleHTTP(w http.ResponseWriter, r *http.Request) {
    w.WriteHeader(http.StatusOK)
    w.Write([]byte("HTTP正常 | WebSocket: ws://localhost:8080/ws"))
}

func main() {
    http.HandleFunc("/", handleHTTP)
    http.HandleFunc("/ws", handleWS)
    log.Fatal(http.ListenAndServe(":8080", nil))
}

3. 测试验证

  1. 测试 HTTP 服务:浏览器访问 http://localhost:8080,可看到状态提示。

  2. 测试 WebSocket 服务:用在线工具(如 WebSocket King)连接 ws://localhost:8080/ws,发送消息即可收到回声响应。

关键说明与扩展

1. 为何能同时提供服务?

Go 的 net/http 服务本质是“请求路由器”,不同路径对应不同处理函数:/ 路径走 HTTP 逻辑,/ws 路径触发 WebSocket 升级,两者共享同一个端口和服务进程,由 Go 原生的协程(Goroutine)高效处理并发连接,性能拉满。

2. 生产环境注意点

  • 跨域限制:示例中 CheckOrigin: return true 允许所有跨域请求,生产环境需替换为具体的域名校验逻辑(如判断 r.Header.Get("Origin") 是否在白名单内)。

  • 连接管理:需维护 WebSocket 连接池(如用 map 存储连接),处理断线重连、心跳检测,避免无效连接占用资源。

  • 性能优化:高并发场景可替换为 gobwas/ws 库(内存占用更低,支持百万级连接),但 gorilla/websocket 足够覆盖绝大多数中小规模场景。

写在最后

Go 凭借原生 net/http 包的灵活性和第三方 WebSocket 库的成熟度,能轻松同时提供 HTTP 和 WebSocket 服务,代码简洁、并发能力强,非常适合开发实时聊天、监控面板、推送服务等场景。