在 React 中,如果需要建立一个全局 WebSocket 连接,使得整个应用的所有页面都可以访问连接并发送消息,可以通过以下方式实现:
实现思路
全局管理 WebSocket 连接:
创建一个独立的 WebSocket 实例管理工具。
使用 React 的 Context 或其他状态管理工具(如 Redux)共享 WebSocket 的状态。
发送与接收消息:
提供统一的发送方法。
通过全局事件监听消息并触发 UI 更新。
全局初始化连接:
在 React 应用启动时(如 App.js),建立 WebSocket 连接。
代码实现
1. 创建 WebSocket 管理工具
创建一个工具类来管理 WebSocket 的连接、消息发送和事件监听。
// websocket.js
class WebSocketService {
static instance = null;
static getInstance() {
if (!this.instance) {
this.instance = new WebSocketService();
}
return this.instance;
}
constructor() {
this.socket = null;
this.callbacks = [];
}
connect(url) {
if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {
this.socket = new WebSocket(url);
this.socket.onopen = () => {
console.log("WebSocket connection established");
};
this.socket.onmessage = (event) => {
this.callbacks.forEach((callback) => callback(event.data));
};
this.socket.onclose = () => {
console.log("WebSocket connection closed");
};
this.socket.onerror = (error) => {
console.error("WebSocket error:", error);
};
}
}
sendMessage(message) {
if (this.socket && this.socket.readyState === WebSocket.OPEN) {
this.socket.send(message);
} else {
console.error("WebSocket is not open");
}
}
addMessageListener(callback) {
this.callbacks.push(callback);
}
removeMessageListener(callback) {
this.callbacks = this.callbacks.filter((cb) => cb !== callback);
}
}
export default WebSocketService;
2. 设置全局 WebSocket 上下文
通过 React 的 Context 提供 WebSocket 全局访问。
创建 Context
// WebSocketContext.js
import React, { createContext, useEffect } from "react";
import WebSocketService from "./websocket";
export const WebSocketContext = createContext(null);
export const WebSocketProvider = ({ children }) => {
const wsService = WebSocketService.getInstance();
useEffect(() => {
wsService.connect("ws://localhost:8080/realtime");
return () => {
// 清理连接
wsService.socket && wsService.socket.close();
};
}, [wsService]);
return (
<WebSocketContext.Provider value={wsService}>
{children}
</WebSocketContext.Provider>
);
};
使用 Context 包裹应用
在 App.js 中使用 WebSocketProvider 包裹整个应用:
// App.js
import React from "react";
import { WebSocketProvider } from "./WebSocketContext";
import YourComponent from "./YourComponent";
function App() {
return (
<WebSocketProvider>
<YourComponent />
</WebSocketProvider>
);
}
export default App;
3. 使用 WebSocket 在组件中收发消息
接收消息
在任何组件中,使用 useContext 获取 WebSocket 实例,并添加消息监听器。
import React, { useContext, useEffect, useState } from "react";
import { WebSocketContext } from "./WebSocketContext";
const MessageReceiver = () => {
const wsService = useContext(WebSocketContext);
const [messages, setMessages] = useState([]);
useEffect(() => {
const handleMessage = (message) => {
setMessages((prevMessages) => [...prevMessages, message]);
};
wsService.addMessageListener(handleMessage);
return () => {
wsService.removeMessageListener(handleMessage);
};
}, [wsService]);
return (
<div>
<h1>Received Messages</h1>
<ul>
{messages.map((msg, index) => (
<li key={index}>{msg}</li>
))}
</ul>
</div>
);
};
export default MessageReceiver;
发送消息
通过 WebSocketContext 获取 sendMessage 方法进行发送。
import React, { useContext, useState } from "react";
import { WebSocketContext } from "./WebSocketContext";
const MessageSender = () => {
const wsService = useContext(WebSocketContext);
const [message, setMessage] = useState("");
const sendMessage = () => {
wsService.sendMessage(message);
setMessage("");
};
return (
<div>
<h1>Send Message</h1>
<input
type="text"
value={message}
onChange={(e) => setMessage(e.target.value)}
placeholder="Type your message"
/>
<button onClick={sendMessage}>Send</button>
</div>
);
};
export default MessageSender;
4. 综合展示
将发送和接收消息的组件组合起来:
import React from "react";
import MessageSender from "./MessageSender";
import MessageReceiver from "./MessageReceiver";
const YourComponent = () => {
return (
<div>
<MessageSender />
<MessageReceiver />
</div>
);
};
export default YourComponent;
优化与扩展
断线重连:
在 onclose 回调中实现自动重连逻辑。
消息类型区分:
使用 JSON 格式传递消息,并根据消息类型(如通知、更新等)动态处理。
状态管理集成:
使用 Redux 或 Zustand 集成 WebSocket 数据更新。
安全认证:
在连接建立前通过 URL 参数或 token 实现认证。
通过以上实现,WebSocket 的连接和功能可以在全局页面访问,同时支持实时消息的发送和接收