Я работаю над приложением 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
) {}
}
Кажется, что функция 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() });
}
}
скорее всего это проблема с универсалом. процесс на сервере подключается к веб-сокету, и из-за этого приложение Angular работает нестабильно. в результате он не считается «готовым» для передачи клиенту. вам следует реорганизовать свой код, чтобы не использовать этот сокет, если он используется не на платформе = браузере