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

相关推荐
Moment1 小时前
从方案到原理,带你从零到一实现一个 前端白屏 检测的 SDK ☺️☺️☺️
前端·javascript·面试
鱼樱前端1 小时前
Vue3 + TypeScript 整合 MeScroll.js 组件
前端·vue.js
拉不动的猪1 小时前
刷刷题29
前端·vue.js·面试
无人不xiao2 小时前
WebSocket
网络·websocket·网络协议
野生的程序媛2 小时前
重生之我在学Vue--第5天 Vue 3 路由管理(Vue Router)
前端·javascript·vue.js
codingandsleeping2 小时前
前端工程化之模块化
前端·javascript
CodeCraft Studio2 小时前
报表控件stimulsoft操作:使用 Angular 应用程序的报告查看器组件
前端·javascript·angular.js
阿丽塔~2 小时前
面试题之vue和react的异同
前端·vue.js·react.js·面试
烛阴3 小时前
JavaScript 性能提升秘籍:WeakMap 和 WeakSet 你用对了吗?
前端·javascript
yuren_xia4 小时前
eclipse创建maven web项目
前端·eclipse·maven