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

Angular 18中使用socketio-client触发页面渲染超时错误求助

解决Angular SSR中Socket.IO连接导致的页面渲染超时问题

问题场景

在开发Angular独立组件应用时,在SocketService的构造函数中直接初始化Socket.IO连接,触发了页面渲染超时错误:

01:05:28 [vite] Internal server error: Page / did not render in 30 seconds.
      at Timeout.<anonymous> (C:\Users\azoul\OneDrive\Bureau\code\dm-front\node_modules\@angular\build\src\utils\server-rendering\render-page.js:90:90)
      at Timeout.timer (C:\Users\azoul\OneDrive\Bureau\code\dm-front\node_modules\zone.js\fesm2015\zone-node.js:2249:37)
      at _ZoneDelegate.invokeTask (C:\Users\azoul\OneDrive\Bureau\code\dm-front\node_modules\zone.js\fesm2015\zone-node.js:398:33)
      at _ZoneImpl.runTask (C:\Users\azoul\OneDrive\Bureau\code\dm-front\node_modules\zone.js\fesm2015\zone-node.js:158:47)
      at invokeTask (C:\Users\azoul\OneDrive\Bureau\code\dm-front\node_modules\zone.js\fesm2015\zone-node.js:479:34)
      at Timeout.ZoneTask.invoke (C:\Users\azoul\OneDrive\Bureau\code\dm-front\node_modules\zone.js\fesm2015\zone-node.js:468:48)
      at Timeout.data.args.<computed> (C:\Users\azoul\OneDrive\Bureau\code\dm-front\node_modules\zone.js\fesm2015\zone-node.js:2231:32)
      at listOnTimeout (node:internal/timers:573:17)
      at process.processTimers (node:internal/timers:514:7)

相关代码:
socket.service.ts

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { io, Socket } from 'socket.io-client';

@Injectable({
  providedIn: 'root'
})
export class SocketService {

  private socket!: Socket;

  constructor() {
    this.socket = io('http://localhost:3000');
  }
}

home.component.ts

import { Component } from '@angular/core';
import { RouterLink } from '@angular/router';
import { SocketService } from '../../core/services/socket.service';
import { io, Socket } from 'socket.io-client';

@Component({
  selector: 'app-home',
  standalone: true,
  imports: [
    RouterLink
  ],
  templateUrl: './home.component.html',
  styleUrl: './home.component.scss'
})
export class HomeComponent {
  
  constructor(
    private socketService: SocketService
  ) {}
}

解决方案

1. 延迟Socket连接初始化,区分运行环境

SSR过程中服务器端无浏览器WebSocket环境,直接在构造函数创建连接会阻塞渲染。需通过isPlatformBrowser判断环境,仅在客户端初始化连接:

修改socket.service.ts:

import { Injectable, PLATFORM_ID, Inject } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';
import { Socket, io } from 'socket.io-client';

@Injectable({
  providedIn: 'root'
})
export class SocketService {
  private socket!: Socket;

  constructor(@Inject(PLATFORM_ID) private platformId: Object) {}

  init(): void {
    if (isPlatformBrowser(this.platformId)) {
      this.socket = io('http://localhost:3000');
      // 可选:添加连接错误监听
      this.socket.on('connect_error', (error) => {
        console.error('Socket连接失败:', error);
      });
    }
  }
}

2. 在组件生命周期钩子中触发初始化

在组件的ngOnInit中调用Socket服务的初始化方法,确保仅在客户端执行:

修改home.component.ts:

import { Component, OnInit } from '@angular/core';
import { RouterLink } from '@angular/router';
import { SocketService } from '../../core/services/socket.service';

@Component({
  selector: 'app-home',
  standalone: true,
  imports: [RouterLink],
  templateUrl: './home.component.html',
  styleUrl: './home.component.scss'
})
export class HomeComponent implements OnInit {
  
  constructor(private socketService: SocketService) {}

  ngOnInit(): void {
    this.socketService.init();
  }
}

核心原因

SSR渲染时,服务器端同步执行服务构造函数,Socket.IO的连接尝试因无浏览器环境而阻塞进程,最终触发30秒超时。通过环境判断延迟初始化,避免了服务器端的无效连接尝试,解决渲染阻塞问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 18:13:31