react websocket 全局访问和响应

发布于:2024-12-22 ⋅ 阅读:(13) ⋅ 点赞:(0)

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