案例场景:
在实际的后台中需要变更某个订单的状态,在官网中不刷新页面,可以自动更新状态
在前端页面实现订单状态的实时更新(不刷新页面),可以通过 WebSocket 的方式与后台保持通信,监听订单状态的变化并更新页面。以下是实现方式的详细说明:
后端支持 WebSocket 服务: 后端需要支持 WebSocket,并在订单状态变更时推送消息到前端。
前端实现 WebSocket 连接: 在官网前端页面通过 WebSocket 接收订单状态变更的通知。
方法 1 :使用 WebSocket(推荐) 本次后端使用GO实现
**检查连接是否成功,**可以在浏览器开发者工具中查看 WebSocket 连接状态。
javascript
const socket = new WebSocket('ws://192.168.0.123:8080/ws')
socket.onopen = () => {
console.log('WebSocket connected')
socket.send('Hello, server!')
}
socket.onmessage = event => {
console.log('Message from server:', event.data)
}
socket.onclose = () => {
console.log('WebSocket connection closed')
}
socket.onerror = error => {
console.error('WebSocket error:', error)
}
javascript
// 建立 WebSocket 连接
const socket = new WebSocket('ws://192.168.0.123:8080/ws')
// 监听连接打开事件
socket.addEventListener('open', () => {
console.log('WebSocket connected')
})
// 接收服务器推送的消息
socket.addEventListener('message', event => {
const data = JSON.parse(event.data)
if (data.orderId && data.status) {
// 假设订单状态在页面中通过订单ID显示
updateOrderStatus(data.orderId, data.status)
}
})
// 更新订单状态的函数
function updateOrderStatus (orderId, newStatus) {
const orderElement = document.querySelector(`#gong`)
if (orderElement) {
orderElement.textContent = newStatus // 假设状态是文本
console.log(`订单 ${orderId} 状态更新为: ${newStatus}`)
}
}
后端推送消息格式(示例):
javascript
{
"orderId": "12345",
"status": "已完成"
}
后端多种语言
1. Node.js 使用ws
库 安装 WebSocket 库npm install ws
javascript
const WebSocket = require('ws');
// 创建 WebSocket 服务
const wss = new WebSocket.Server({ port: 8080 });
wss.on('connection', (ws) => {
console.log('客户端已连接');
// 接收消息
ws.on('message', (message) => {
console.log(`收到消息: ${message}`);
});
// 向客户端发送消息
ws.send(JSON.stringify({ orderId: '12345', status: '已完成' }));
// 模拟订单状态更新推送
setInterval(() => {
ws.send(JSON.stringify({ orderId: '12345', status: '已完成' }));
}, 5000);
});
console.log('WebSocket 服务已启动,监听端口 8080');
2、Python 使用
FastAPI
和****websockets安装依赖
pip install fastapi uvicorn websockets
javascript
from fastapi import FastAPI, WebSocket
import asyncio
app = FastAPI()
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
print("客户端已连接")
# 模拟向客户端发送订单状态
while True:
await asyncio.sleep(5)
await websocket.send_json({"orderId": "12345", "status": "已完成"})
启动服务
uvicorn main:app --reload --host 0.0.0.0 --port 8000
3、Java 使用 Spring Boot添加依赖
在
pom.xml
中添加 Spring WebSocket 依赖:
XML
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
java
配置 WebSocket
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(new OrderStatusHandler(), "/ws").setAllowedOrigins("*");
}
}
java
WebSocket Handler
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import org.springframework.web.socket.TextMessage;
public class OrderStatusHandler extends TextWebSocketHandler {
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
System.out.println("客户端已连接");
// 模拟订单状态推送
new Thread(() -> {
try {
while (true) {
session.sendMessage(new TextMessage("{\"orderId\": \"12345\", \"status\": \"已完成\"}"));
Thread.sleep(5000);
}
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
}
3、Go 使用****gorilla/websocket
安装依赖
go get github.com/gorilla/websocket
Go
package main
import (
"fmt"
"net/http"
"time"
"github.com/gorilla/websocket"
)
var upgrader = websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool { return true },
}
func handler(w http.ResponseWriter, r *http.Request) {
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
fmt.Println("连接失败:", err)
return
}
defer conn.Close()
fmt.Println("客户端已连接")
// 模拟订单状态推送
for {
time.Sleep(5 * time.Second)
err = conn.WriteJSON(map[string]interface{}{
"orderId": "12345",
"status": "已完成",
})
if err != nil {
fmt.Println("发送消息失败:", err)
break
}
}
}
func main() {
http.HandleFunc("/ws", handler)
fmt.Println("WebSocket 服务已启动,监听端口 8080")
http.ListenAndServe(":8080", nil)
}
最佳实践:
- 在实际生产环境中,可以结合 消息队列(如 Kafka、RabbitMQ)处理大规模 WebSocket 消息推送。
- 实现断线重连功能,确保客户端始终连接到服务端。
- 基本规则
WebSocket 使用 ws:// 或 wss:// 协议:
ws://
:用于未加密的连接(通常在本地或不使用 HTTPS 的环境中使用)。wss://
:用于加密的连接(必须在 HTTPS 环境中使用)。- 地址的格式类似于 HTTP,但协议是 WebSocket,端口与后端配置保持一致:
- ws://host:port/path
wss://host:port/path- 确保
/ws
路径与后端路由匹配。