react websocket 全局访问和响应

在 React 中,如果需要建立一个全局 WebSocket 连接,使得整个应用的所有页面都可以访问连接并发送消息,可以通过以下方式实现:

实现思路

全局管理 WebSocket 连接:

创建一个独立的 WebSocket 实例管理工具。

使用 React 的 Context 或其他状态管理工具(如 Redux)共享 WebSocket 的状态。

发送与接收消息:

提供统一的发送方法。

通过全局事件监听消息并触发 UI 更新。

全局初始化连接:

在 React 应用启动时(如 App.js),建立 WebSocket 连接。

代码实现

1. 创建 WebSocket 管理工具

创建一个工具类来管理 WebSocket 的连接、消息发送和事件监听。

js 复制代码
// 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

js 复制代码
// 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 包裹整个应用:

bash 复制代码
// 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 实例,并添加消息监听器。

js 复制代码
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 方法进行发送。

js 复制代码
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. 综合展示

将发送和接收消息的组件组合起来:

js 复制代码
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 的连接和功能可以在全局页面访问,同时支持实时消息的发送和接收

相关推荐
朱 欢 庆7 小时前
云服务器附件备份到本机内网服务器
运维·服务器·前端·经验分享
Sylvia33.7 小时前
LOL实时数据接入深度解析:从WebSocket到完整数据模型
java·网络·python·websocket·网络协议
支支დ12 小时前
VO by Vercel 前端特定优势:为什么它是构建 AI 应用的新范式
前端·人工智能
香芋芋圆13 小时前
AI 冲击内卷之下,普通前端如何破局?WebGIS—— 低门槛突围赛道
前端·javascript·人工智能·学习·职场发展
INS_KF13 小时前
【编程笔记】成员函数中两个 const 的区别(const Data &getData() const;)
前端·javascript·笔记
宿67414 小时前
vue3-async
前端·javascript·vue.js
YXWik614 小时前
记录前端请求接口在浏览器请求响应的Preview和Response展示的一样的问题
前端
2501_9289962214 小时前
GPT-4o换DeepSeek迁移成本多少?中科热备解析API聚合平台技术账本
前端·数据库·人工智能
东风破_14 小时前
从跨域到 WebSocket:前端跨域方案、SSE 与双向实时通信详解
前端·后端
原则猫14 小时前
TS 类型工具
前端