Я пытаюсь создать веб-приложение для игры, которая включает запуск и присоединение комнат. Я использую Angular и Socket.io для проекта. У меня есть компоненты с названиями Startpage и Lobby. Стартовая страница содержит текстовые поля для имени игрока и ID комнаты. На нем также есть кнопки «Начать игру» и «Присоединиться к игре». При нажатии на кнопку «Начать игру» запускается функция startThisGame ().
//startpage.component.ts
import { Component, OnInit, Output, NgZone } from '@angular/core';
import { Router } from '@angular/router';
import { SocketioService } from '../socketio.service';
@Component({
selector: 'app-startpage',
templateUrl: './startpage.component.html',
styleUrls: ['./startpage.component.css']
})
export class StartpageComponent implements OnInit {
constructor( private router: Router, public zone: NgZone, private socketService: SocketioService ) {}
ngOnInit() {
this.socketService.setupSocketConnection();
}
testRoomId = 'xxxx'
startThisGame() {
var playerName = (document.getElementById("nameInput") as HTMLInputElement).value;
if (playerName) {
this.testRoomId = this.socketService.startGame(playerName);
alert("In component: " + this.testRoomId)
this.zone.run(() => {this.router.navigate(['/lobby']); });
}
else{
alert("Enter a player name!")
}
}
}
Код внутри socketService выглядит следующим образом.
import { Injectable } from '@angular/core';
import * as io from 'socket.io-client';
import { environment } from 'src/environments/environment';
@Injectable({
providedIn: 'root'
})
export class SocketioService {
socket;
public roomId: string;
public playerName: string;
constructor() {}
setupSocketConnection() {
this.socket = io(environment.SOCKET_ENDPOINT)
alert("Connection set-up")
}
startGame(inputPlayerName) {
this.socket.emit('startGame', {name: inputPlayerName})
this.playerName = inputPlayerName
this.socket.on('recieveRoomId', (data: any) => {
this.roomId = data.code
alert("In service startGame: " + this.roomId)
})
return this.roomId
}
getRoomId() {
alert("In service getRoomId: " + this.roomId)
return this.roomId;
}
}
Код сервера создает уникальный идентификатор комнаты и передает его переменной roomId в socketService. Мой первый вопрос начинается здесь. Если вы заметили, я оставил за собой след предупреждающих сообщений. Я ожидаю, что порядок предупреждений будет alert("In service startGame: " + this.roomId)
, а затем alert("In component: " + this.testRoomId)
. Однако я получаю сообщения с предупреждениями в обратном порядке, и roomId не определен, хотя сервер генерирует и выдает уникальный roomId. Мне кажется, я не понимаю, почему это происходит.
Во-вторых, вы можете видеть, что функция startThisGame()
заставляет socketService сохранять сгенерированные roomId
и playerName
внутри класса, а затем перенаправляет приложение на компонент лобби. Код лобби выглядит следующим образом:
import { Component, OnInit, OnChanges, AfterContentInit, SimpleChanges, Input } from '@angular/core';
import { SocketioService } from '../socketio.service';
@Component({
selector: 'app-lobby',
templateUrl: './lobby.component.html',
styleUrls: ['./lobby.component.css']
})
export class LobbyComponent implements OnInit, AfterContentInit {
constructor(private socketService: SocketioService) { }
@Input() roomId: string;
ngOnInit(): void {
// alert("On init fetched")
this.socketService.setupSocketConnection()
this.roomId = this.socketService.getRoomId()
if (this.roomId) {
alert("Value obtained in init: " + this.roomId)
}
else {
alert("No value obtained inside init")
}
document.getElementById("generated_code").innerHTML = this.roomId
}
}
Здесь OnInit, функция socketService.getRoomId () возвращает неопределенное значение. Если я снова вернусь, go на стартовую страницу, введу playerName и снова начну новую игру, будет отображаться ранее созданный roomId. Что мне здесь не хватает? Как мне загрузить roomId и отобразить его при перенаправлении в лобби?