Ant Design Pro 中 WebSocket 实战指南:从零搭建实时通信系统
快速体验
在开始今天关于 Ant Design Pro 中 WebSocket 实战指南:从零搭建实时通信系统 的探讨之前,我想先分享一个最近让我觉得很有意思的全栈技术挑战。
我们常说 AI 是未来,但作为开发者,如何将大模型(LLM)真正落地为一个低延迟、可交互的实时系统,而不仅仅是调个 API?
这里有一个非常硬核的动手实验:基于火山引擎豆包大模型,从零搭建一个实时语音通话应用。它不是简单的问答,而是需要你亲手打通 ASR(语音识别)→ LLM(大脑思考)→ TTS(语音合成)的完整 WebSocket 链路。对于想要掌握 AI 原生应用架构的同学来说,这是个绝佳的练手项目。

从0到1构建生产级别应用,脱离Demo,点击打开 从0打造个人豆包实时通话AI动手实验
Ant Design Pro 中 WebSocket 实战指南:从零搭建实时通信系统
在现代管理后台系统中,实时通信能力已成为标配需求。无论是实时数据监控看板、即时消息通知,还是多人协作编辑场景,WebSocket 技术都能提供高效的解决方案。与传统的轮询方式相比,WebSocket 建立的持久化连接可以显著降低服务器负载,同时实现毫秒级的消息推送。
技术选型:Socket.IO vs 原生 WebSocket
在 Ant Design Pro 项目中集成 WebSocket 时,我们通常面临两种选择:
-
原生 WebSocket
- 优点:浏览器原生支持,无额外依赖,性能最优
- 缺点:需手动实现断线重连、心跳检测等机制
- 适用场景:对包体积敏感,需要极致性能的项目
-
Socket.IO
- 优点:自动重连、心跳检测等开箱即用,支持房间和命名空间
- 缺点:增加约 30KB 包体积,协议开销略大
- 适用场景:需要快速实现稳定通信的复杂应用
对于大多数 Ant Design Pro 项目,如果已经使用 TypeScript 和现代前端工具链,推荐使用原生 WebSocket 以获得更好的性能和可控性。下面我们将基于原生方案进行实现。
核心实现方案
1. 封装 WebSocket 服务类
首先创建一个可复用的 WebSocket 服务,使用 TypeScript 强化类型安全:
// src/services/websocket.ts
type MessageHandler = (data: any) => void;
class WebSocketService {
private socket: WebSocket | null = null;
private messageHandlers = new Set<MessageHandler>();
private reconnectAttempts = 0;
private maxReconnectAttempts = 5;
private reconnectDelay = 1000;
private heartbeatInterval = 30000;
private heartbeatTimer?: number;
constructor(private url: string) {}
connect(token: string): Promise<void> {
return new Promise((resolve, reject) => {
this.socket = new WebSocket(`${this.url}?token=${encodeURIComponent(token)}`);
this.socket.onopen = () => {
this.reconnectAttempts = 0;
this.startHeartbeat();
resolve();
};
this.socket.onerror = (error) => {
reject(error);
};
this.socket.onmessage = (event) => {
try {
const data = JSON.parse(event.data);
this.messageHandlers.forEach(handler => handler(data));
} catch (e) {
console.error('WebSocket message parse error:', e);
}
};
this.socket.onclose = () => {
this.stopHeartbeat();
this.attemptReconnect();
};
});
}
private startHeartbeat() {
this.heartbeatTimer = window.setInterval(() => {
this.send({ type: 'heartbeat' });
}, this.heartbeatInterval);
}
private stopHeartbeat() {
if (this.heartbeatTimer) {
clearInterval(this.heartbeatTimer);
}
}
private attemptReconnect() {
if (this.reconnectAttempts < this.maxReconnectAttempts) {
this.reconnectAttempts++;
setTimeout(() => {
this.connect(localStorage.getItem('token') || '');
}, this.reconnectDelay);
}
}
send(data: Record<string, any>) {
if (this.socket?.readyState === WebSocket.OPEN) {
this.socket.send(JSON.stringify(data));
}
}
subscribe(handler: MessageHandler) {
this.messageHandlers.add(handler);
return () => this.messageHandlers.delete(handler);
}
disconnect() {
this.socket?.close();
this.stopHeartbeat();
}
}
export const webSocketService = new WebSocketService(process.env.WS_API || 'ws://localhost:8080');
2. 与 Redux/Dva 集成
在 Ant Design Pro 的模型层集成 WebSocket 消息处理:
// src/models/websocket.ts
import { webSocketService } from '@/services/websocket';
import { Effect, Reducer } from 'umi';
interface WebSocketState {
lastMessage?: any;
connected: boolean;
}
interface WebSocketModelType {
namespace: 'websocket';
state: WebSocketState;
effects: {
connect: Effect;
sendMessage: Effect;
};
reducers: {
updateState: Reducer<WebSocketState>;
};
}
const WebSocketModel: WebSocketModelType = {
namespace: 'websocket',
state: {
connected: false,
},
effects: {
*connect(_, { call, put }) {
try {
yield call(webSocketService.connect, localStorage.getItem('token') || '');
yield put({ type: 'updateState', payload: { connected: true } });
const unsubscribe = webSocketService.subscribe((data) => {
put({ type: 'updateState', payload: { lastMessage: data } });
// 根据消息类型触发其他 action
if (data.type === 'notification') {
put({ type: 'notification/add', payload: data });
}
});
return unsubscribe;
} catch (error) {
console.error('WebSocket connect failed:', error);
}
},
*sendMessage({ payload }, { call }) {
yield call(webSocketService.send, payload);
},
},
reducers: {
updateState(state, { payload }) {
return { ...state, ...payload };
},
},
};
export default WebSocketModel;
3. React 组件集成示例
使用 Hooks 在组件中集成 WebSocket:
// src/pages/RealTimeMonitor/index.tsx
import React, { useEffect } from 'react';
import { useDispatch, useSelector } from 'umi';
import { Card, Space, notification } from 'antd';
const RealTimeMonitor: React.FC = () => {
const dispatch = useDispatch();
const { lastMessage, connected } = useSelector((state: any) => state.websocket);
useEffect(() => {
const unsubscribe = dispatch({
type: 'websocket/connect'
});
return () => {
if (unsubscribe) unsubscribe();
};
}, [dispatch]);
useEffect(() => {
if (lastMessage?.type === 'alert') {
notification.warning({
message: '系统告警',
description: lastMessage.content,
});
}
}, [lastMessage]);
return (
<Card title="实时监控看板" loading={!connected}>
<Space direction="vertical">
<div>连接状态: {connected ? '已连接' : '断开'}</div>
{lastMessage && (
<pre>{JSON.stringify(lastMessage, null, 2)}</pre>
)}
</Space>
</Card>
);
};
export default RealTimeMonitor;
性能优化策略
1. 大规模连接内存管理
- 使用 WeakMap 存储消息处理器,避免内存泄漏
- 实现消息分片处理,避免大消息阻塞
- 对于高频更新数据,考虑差异更新策略
2. 消息频率控制
// 节流处理高频消息
const throttledHandlers = new Map<MessageHandler, MessageHandler>();
function throttleHandler(handler: MessageHandler, delay = 100): MessageHandler {
if (throttledHandlers.has(handler)) {
return throttledHandlers.get(handler)!;
}
let lastExec = 0;
const throttled = (data: any) => {
const now = Date.now();
if (now - lastExec >= delay) {
handler(data);
lastExec = now;
}
};
throttledHandlers.set(handler, throttled);
return throttled;
}
3. WebSocket 与 HTTP API 协同
- 初始化数据使用 HTTP 请求
- 实时更新使用 WebSocket 推送
- 实现数据版本控制,避免冲突
安全注意事项
1. JWT 鉴权实现
// WebSocket 连接时携带 JWT
const token = localStorage.getItem('token');
webSocketService.connect(token);
2. 消息内容加密
- 对敏感字段使用 AES 加密
- 实现端到端加密方案
- 使用消息签名防止篡改
生产环境检查清单
- 连接稳定性:验证断网自动重连机制,确保最多重试次数限制
- 内存泄漏:长时间运行后检查内存占用,确保无持续增长
- 心跳检测:确认30秒无活动后心跳包能正常发送和响应
- 认证失效:测试JWT过期后是否能正确处理重新认证流程
- 压力测试:模拟100+并发连接,验证服务端和客户端性能
通过以上实现,我们构建了一个健壮的WebSocket集成方案,能够满足Ant Design Pro项目中各种实时通信需求。完整代码示例已通过ESLint校验,可直接集成到现有项目中。
如果你想体验更完整的AI实时通信方案,可以参考从0打造个人豆包实时通话AI实验项目,它提供了从语音识别到智能对话的完整实现链路。
实验介绍
这里有一个非常硬核的动手实验:基于火山引擎豆包大模型,从零搭建一个实时语音通话应用。它不是简单的问答,而是需要你亲手打通 ASR(语音识别)→ LLM(大脑思考)→ TTS(语音合成)的完整 WebSocket 链路。对于想要掌握 AI 原生应用架构的同学来说,这是个绝佳的练手项目。
你将收获:
- 架构理解:掌握实时语音应用的完整技术链路(ASR→LLM→TTS)
- 技能提升:学会申请、配置与调用火山引擎AI服务
- 定制能力:通过代码修改自定义角色性格与音色,实现“从使用到创造”
从0到1构建生产级别应用,脱离Demo,点击打开 从0打造个人豆包实时通话AI动手实验
更多推荐


所有评论(0)