You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Electron(Next.js/React)中实现WebSocket客户端?

在Nextron(Next.js + Electron)中正确使用WebSocket的位置

你遇到的问题根源是:Next.js的服务端渲染(SSR)机制会在服务端执行组件顶层代码,而服务端环境没有浏览器提供的WebSocket API,直接在_app.tsx组件顶层创建实例会触发报错。Electron的渲染进程本身支持WebSocket,但必须确保代码只在客户端环境执行。

正确的实现方式

将WebSocket的初始化逻辑放到useEffect钩子中,并使用useRef持久化实例,避免组件重渲染时重复创建连接:

import React from 'react';
import Head from 'next/head';
import { ThemeProvider } from '@material-ui/core/styles';
import CssBaseline from '@material-ui/core/CssBaseline';
import { theme } from '../lib/theme';
import type { AppProps } from 'next/app';

export default function (props: AppProps) {
  const { Component, pageProps } = props;
  // 用useRef持久化WebSocket实例,避免组件重渲染时重复创建
  const wsRef = React.useRef<WebSocket | null>(null);

  React.useEffect(() => {
    // 仅在客户端环境初始化WebSocket
    if (typeof window !== 'undefined') {
      const ws = new WebSocket("ws://192.168.100.8:8081/");
      wsRef.current = ws;

      // 可以在这里添加WebSocket的事件监听
      ws.onopen = () => {
        console.log("WebSocket连接已建立");
      };

      ws.onmessage = (event) => {
        console.log("收到WebSocket消息:", event.data);
      };

      ws.onerror = (error) => {
        console.error("WebSocket错误:", error);
      };

      ws.onclose = () => {
        console.log("WebSocket连接已关闭");
      };
    }

    // 组件卸载时关闭WebSocket连接,防止内存泄漏
    return () => {
      if (wsRef.current) {
        wsRef.current.close();
      }
    };
  }, []); // 空依赖数组确保只执行一次

  React.useEffect(() => {
    const jssStyles = document.querySelector('#jss-server-side');
    if (jssStyles) {
      jssStyles.parentElement.removeChild(jssStyles);
    }
  }, []);

  return (
    <React.Fragment>
      <Head>
        <meta name="viewport" content="minimum-scale=1, initial-scale=1, width=device-width" />
      </Head>
      <ThemeProvider theme={theme}>
        <CssBaseline />
        <Component {...pageProps} />
      </ThemeProvider>
    </React.Fragment>
  );
}

关键注意点

  • 客户端环境判断:通过typeof window !== 'undefined'确保代码只在浏览器/Electron渲染进程执行,避开服务端渲染阶段。
  • 实例持久化:使用useRef存储WebSocket实例,保证组件重渲染时不会重新创建连接。
  • 生命周期清理:在useEffect的返回函数中关闭连接,避免组件卸载后残留无效连接。
  • Electron安全策略:如果连接失败,检查Electron的contentSecurityPolicy配置,确保允许连接到目标WebSocket服务器地址。

扩展方案

如果需要在多个组件中使用WebSocket,可以将其封装为自定义Hook或者React Context,实现全局状态管理和事件分发,方便各组件共享连接状态和消息。

内容的提问来源于stack exchange,提问作者DennyHiu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 20:40:10