Socketio-client вызывает «Внутреннюю ошибку сервера: страница / не отображается в течение 30 секунд» в Angular 18

Я работаю над приложением Angular, где использую Socketio-клиент внутри SocketService. Однако при попытке использовать соединение сокета в конструкторе службы я сталкиваюсь со следующей ошибкой:

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)

сокет.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.comComponent.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 // I use standalone components
  ],
  templateUrl: './home.component.html',
  styleUrl: './home.component.scss'
})
export class HomeComponent {
  
  constructor(
    private socketService: SocketService
  ) {}
}

скорее всего это проблема с универсалом. процесс на сервере подключается к веб-сокету, и из-за этого приложение Angular работает нестабильно. в результате он не считается «готовым» для передачи клиенту. вам следует реорганизовать свой код, чтобы не использовать этот сокет, если он используется не на платформе = браузере

Andrei 27.06.2024 09:19
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
2
1
407
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Кажется, что функция io автоматически подключает клиента к данному серверу (http://localhost:3000). Поэтому, когда Angular инициализирует приложение, вы подключаетесь к веб-сокету. Но вы никогда не отключитесь, так как не вызвали методocket.disconnect() (илиsocket.close). Это означает, что Angular Zone.js, вероятно, будет иметь некоторые ожидающие задачи, связанные с соединением через сокет, и поэтому никогда не будет считать приложение стабильным. А Angular требует, чтобы приложение было стабильным (без каких-либо ожидающих задач), чтобы его можно было считать инициализированным.

Чтобы решить эту проблему, вы можете запустить сокет после того, как Angular завершит инициализацию приложения. Для этого вы можете подключить сокет, как только приложение станет стабильным.

Таким образом, приложение запустится как обычно. Затем, когда соединение будет стабильным, соединение с веб-сокетом будет постоянным, что сделает приложение нестабильным. Но это нормально, когда все загрузилось. И это имеет смысл, поскольку данные постоянно поступают из веб-сокета, пока вы его не закроете.

Например, это может быть обновленная служба сокетов:

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


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

  constructor() {
    this.socket = io('http://localhost:3000', { autoConnect: false });
    inject(ApplicationRef).isStable.pipe(
      first((isStable) => isStable))
    .subscribe(() => { this.socket.connect() });
  }
}

Другие вопросы по теме