第 11 章:使用 WebSockets
WebSockets 技术为云原生应用带来实时双向通信能力,极大提升了用户体验和系统交互性。本章将系统介绍 WebSockets 的原理、云原生适应性及第三方消息服务集成实践。
引言
过去,Web 应用需要手动刷新才能获取最新数据。如今,实时交互已成为网站标配,WebSockets 和服务器发送事件(SSE)技术让前端与后端实现高效的双向或单向通信,极大提升了用户体验和系统响应能力。
本章主要内容包括:
- WebSockets 原理与云端适用性
- 第三方消息服务集成 WebSockets 应用
- 架构设计与代码实现
WebSockets 技术解析
WebSockets 允许浏览器与服务器之间建立持久的双向通信通道,适用于实时通知、在线聊天、游戏等场景。相比传统 HTTP 请求,WebSockets 通过连接升级实现协议转换,支持高效的数据交换。
WebSockets 工作原理
WebSockets 由客户端发起,通过 HTTP 连接升级为 WebSockets 协议。请求示例:
GET /game HTTP/1.1
Host: server.mygame.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: awesomegame
Sec-WebSocket-Version: 13
Origin: http://mygame.com
服务器响应:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: awesomegame
客户端可通过标准 JavaScript API 建立连接:
var socket = new WebSocket('ws://server.mygame.com');
随后可定义事件处理函数,实现消息收发。
WebSockets 与 SSE 对比
WebSockets 支持全双工通信,SSE 仅支持服务器向客户端单向推送。WebSockets 适合复杂交互场景,SSE 适合轻量级通知。两者在云原生架构下均需关注连接管理与扩展性。
WebSockets 服务器设计要点
设计 WebSockets 服务器需关注以下方面:
- 支持连接升级与协议转换
- 管理所有 WebSockets 连接映射
- 支持广播与定向消息推送
- 连接关闭时及时清理资源
WebSockets 的云原生适应性
WebSockets 连接具有有状态性,易受实例扩展影响。云原生应用强调无状态和可扩展性,需避免单实例连接孤岛问题。如下图所示:

为实现跨实例通信,建议将 WebSockets 组件抽离至后端消息服务,实现统一消息分发和连接管理:

集成第三方消息服务实现 WebSockets 应用
推荐使用 PubNub 等第三方消息服务,支持发布 - 订阅模式,简化消息分发与连接管理。PubNub 提供免费账户和丰富的功能,适合云原生场景。
前端集成 PubNub 示例
以下代码展示了如何在前端订阅和发布消息,实现实时聊天功能:
<!-- assets/templates/index.html JavaScript snippet -->
<script src="http://cdn.pubnub.com/pubnub-3.14.4.min.js"></script>
<script>
var source = "{{ .Email }}";
pubnub = PUBNUB({
publish_key : '{{ .PubKey }}',
subscribe_key : '{{ .SubKey }}'
});
console.log("Subscribing..");
pubnub.subscribe({
channel : "hello_world",
message : function (message, envelope, channelOrGroup, time, channel) {
console.log(
"Message Received." + "\n" +
"Channel or Group: " + JSON.stringify(channelOrGroup) + "\n" +
"Channel: " + JSON.stringify(channel) + "\n" +
"Message: " + JSON.stringify(message) + "\n" +
"Time: " + time + "\n" +
"Raw Envelope: " + JSON.stringify(envelope)
);
var newDiv = document.createElement('div')
newDiv.innerHTML = message
var oldDiv = document.getElementById('chatLog')
oldDiv.appendChild(newDiv)
},
connect: pub
});
function pub(txt) {
console.log("About to publish: " + txt);
pubnub.publish({
channel : "hello_world",
message : "[" + source + "]: " + txt,
callback: function(m){ console.log(m);}
})
}
function publish() {
console.log("Going to publish on demand")
txt = document.getElementById("theText").value;
pub(txt)
}
</script>
该代码通过模板变量注入服务端信息,实现用户身份与消息服务的绑定。
服务端广播消息示例
服务端可通过 PubNub Go SDK 向所有客户端广播消息:
// filepath: server/broadcast_handler.go
package server
import (
"fmt"
"net/http"
"github.com/pubnub/go/messaging"
"github.com/unrolled/render"
)
func broadcastHandler(messagingConfig *pubsubConfig) http.HandlerFunc {
formatter := render.New(render.Options{
IndentJSON: true,
})
pubnub := messaging.NewPubnub(messagingConfig.PublishKey,
messagingConfig.SubscribeKey, "", "", false, "")
channel := "hello_world"
return func(w http.ResponseWriter, r *http.Request) {
successChannel := make(chan []byte)
errorChannel := make(chan []byte)
go pubnub.Publish(channel, "[SYSTEM] Broadcast from the server!",
successChannel, errorChannel)
select {
case response := <-successChannel:
fmt.Printf("pubnub publish response: %s\n", string(response))
case err := <-errorChannel:
fmt.Printf("pubnub publish error: %s\n", string(err))
case <-messaging.Timeout():
fmt.Println("pubnub publish() timeout")
}
formatter.JSON(w, http.StatusOK, nil)
}
}
该处理器通过 goroutine 异步推送消息,并使用 select 语句处理结果。
运行与部署 WebSockets 应用
运行 WebSockets 示例需配置 Auth0 和 PubNub 账户,并在 local_config/env 文件中设置相关密钥。启动服务后,用户可通过 OAuth 登录并访问 /chat 页面,体验实时聊天功能。
如需服务端广播消息,可通过如下命令触发:
curl -X POST http://192.168.99.100/broadcast
浏览器端会收到系统广播消息,支持多用户、多标签页实时互动。

关于 JavaScript 框架
示例代码采用原生 JavaScript,便于理解消息服务集成原理。实际项目可结合 React、Vue 等现代前端框架,提升代码可维护性和用户体验。
总结
本章系统介绍了 WebSockets 技术原理、云原生架构适应性及第三方消息服务集成方法。通过 PubNub 等服务实现高可扩展性和实时交互能力,极大提升了云原生应用的用户体验。建议结合实际项目,深入理解消息服务与 WebSockets 的集成模式,为后续复杂系统开发打下坚实基础。
参考文献
- WebSockets 标准 - developer.mozilla.org
- PubNub 官方文档 - pubnub.com
- Go 官方网站 - golang.org
- Building Microservices - oreilly.com