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

相关推荐
练习两年半的工程师2 小时前
使用React和google gemini api 打造一个google gemini应用
javascript·人工智能·react.js
姑苏洛言4 小时前
30天搭建消防安全培训小程序
前端
左钦杨4 小时前
Nuxt2 vue 给特定的页面 body 设置 background 不影响其他页面
前端·javascript·vue.js
yechaoa5 小时前
【揭秘大厂】技术专项落地全流程
android·前端·后端
MurphyChen5 小时前
🤯 一行代码,优雅的终结 React Context 嵌套地狱!
前端·react.js
逛逛GitHub5 小时前
推荐 10 个受欢迎的 OCR 开源项目
前端·后端·github
_xaboy5 小时前
开源 FormCreate 表单设计器配置组件的多语言
前端·vue.js·低代码·开源·可视化表单设计器
uglyduckling04125 小时前
小程序构建NPM失败
前端·小程序·npm
草原上唱山歌5 小时前
C/C++都有哪些开源的Web框架?
前端·c++·开源
烛阴5 小时前
JavaScript 调度:setTimeout 和 setInterval
前端·javascript