SocketIO web套接字必须放在Angular Service类中



我使用Angular和SocketIO来构建一个纸牌游戏模拟器。我有一个游戏服务,使用web套接字发送和接收来自服务器的消息。

如果我把web套接字作为服务的私有属性,一切都可以正常工作。

@Injectable()
export class GameService {
private socket = io(environment.ws_url
playCards(card): {
this.socket.emit('play_card', card)
}
...

这个方法的问题是,我想在多个地方使用这个GameService。如果我在多个地方使用该服务,就会创建不必要的套接字连接。

我已经尝试将套接字设置为像这样的常量

const socket = io(environment.ws_url)
@Injectable()
export class GameService {
playCards(card): {
socket.emit('play_card', card)
}
}
...

这可以确保每个客户端只创建一个连接。但是,来自服务器的响应需要5秒才能被前端接收,并且UI只更新来自执行操作的客户机的响应。知道为什么吗?

如何确保每个客户端只有一个web套接字,并且仍然在其他组件中重用套接字/服务?

我真的希望能够在多个地方使用这项服务,因为它会使事情变得容易得多。

作为一种变通方法,我总是可以从组件向根组件发射事件,根组件将是GameService的唯一导入器。这种方法非常麻烦,我希望避免这样做

编辑:我想我的问题来自于套接字通信有时在角区之外完成。用this.ngZone.run(() => observer.next(data))包装套接字响应解决了我的问题,并允许我在不创建新连接的情况下在多个地方使用服务。

我可以通过使用这个方法在每个客户端上创建一个连接

const socket = io(environment.ws_url);
@Injectable()
export class GameService {
constructor(private ngZone: NgZone) {}
private socket = socket;
private createObservalble<T>(message: string): Observable<T> {
const observable = new Observable<T>((observer) => {
this.socket.on(message, (data: T) => {
this.ngZone.run(() => observer.next(data));
// In case of error, disconnect
return () => this.socket.disconnect();
});
});
return observable;
}

使用这种方法会导致套接字通信发生在角区之外,我需要添加this.ngZone.run(() => observer.next(data));行来强制UI更新

最新更新