Оператор Socketio.emit не обновляет браузер при вызове из функции, управляемой таймеромPython

Программы на Python
Ответить
Anonymous
 Оператор Socketio.emit не обновляет браузер при вызове из функции, управляемой таймером

Сообщение Anonymous »

Я новичок в Python и Flask и пишу простую программу для онлайн-игры, в которой люди присоединяются к игре, хост вводит слово в свою административную область, и игроки должны угадать это слово. Установлен таймер, и по истечении времени, если никто не угадал слово, отображается таблица лидеров. Если кто-то угадает слово, таблица лидеров отображается до истечения таймера.
Я не могу понять, почему таблица лидеров отображается в браузере нормально при вызове из функции, которая оценивает, Ввод игроков соответствует игровому слову, но не работает, когда из процесса таймера вызывается одна и та же функция.
Я включил ведение журнала, и оба пути правильно сообщают о своем статусе и имеют правильные переменные в игре.
Это это функция (update_leaderboard), которая отлично работает при вызове из функции, которая определяет, что догадка игрока соответствует игровому слову, но не из функции, которая является частью пути таймера.

Код: Выделить всё

def update_leaderboard():
logging.debug(f"Players before updating leaderboard: {game_state['players']}")
leaderboard = sorted(
game_state["players"].values(),
key=lambda p: p["score"],
reverse=True
)
game_state["leaderboard"] = leaderboard
if not leaderboard:
payload = {"leaderboard": [{"name": "No winners this round", "score": 0}]}
else:
payload = {"leaderboard": leaderboard}

logging.info(f"Emitting update_leaderboard with payload: {payload}")
socketio.emit("update_leaderboard", payload, to=None)
Функция submit_answer, которая вызывает функцию update_leaderboard, и все работает как положено:

Код: Выделить всё

@socketio.on("submit_answer")
def handle_answer(data):
sid = request.sid
answer = data.get("answer", "").strip()

logging.debug(f"Player {sid} submitted answer: {answer}")
logging.debug(f"Current players: {game_state['players']}")

# Ensure the round_word is set
if not game_state["round_word"]:
logging.error("Round word is not set.")
emit("error", {"message": "Round word is not set."}, to=sid)
return

# Ensure the player exists in game_state
if sid not in game_state["players"]:
logging.error(f"Player with sid {sid} not found in game_state['players'].")
emit("error", {"message": "Player not found.  Please join the game first."}, to=sid)
return

# Ensure the "score" key exists
game_state["players"][sid].setdefault("score", 0)

# Validate the player's answer
correct = answer.lower() == game_state["round_word"].lower()
if correct:
submission_time = time.time()
elapsed_time = submission_time - game_state["start_time"]
points = max(100 - int(elapsed_time * 10), 0)

if not isinstance(points, (int, float)):
logging.error(f"Invalid points value: {points}")
emit("error", {"message": "Invalid points calculation."}, to=sid)
return

game_state["players"][sid]["score"] += points
logging.info(f"Player {sid} scored {points} points.")
update_leaderboard()  # Update leaderboard after a correct answer
else:
logging.info(f"Player {sid} gave an incorrect answer.")
функция завершения раунда, управляемая функцией ent_round_timer, которая также вызывает update_leaderboard, и обновление дисплея не происходит:

Код: Выделить всё

def end_round_timer(duration):
logging.info(f"Starting end_round_timer with duration: {duration} seconds.")
threading.Timer(duration, end_round).start()

def end_round():
logging.info("Ending round and updating leaderboard.")
update_leaderboard()
logging.info("Called update_leaderboard.")
socketio.emit("round_ended", {"leaderboard": game_state["leaderboard"]}, to=None)
Это JS, который выполняется update_leaderboard:

Код: Выделить всё

socket.on("update_leaderboard", (data) => {
console.log("Received update_leaderboard event:", data);

const leaderboardElement = document.getElementById("leaderboard-screen");
if (leaderboardElement) {
leaderboardElement.innerHTML = ""; // Clear existing leaderboard
if (data.leaderboard.length === 0) {
const li = document.createElement("li");
li.textContent = "No winners this round.";
leaderboardElement.appendChild(li);
} else {
data.leaderboard.forEach((player, index) => {
const li = document.createElement("li");
li.textContent = `${index + 1}. ${player.name} - ${player.score} points`;
leaderboardElement.appendChild(li);
});
}
} else {
console.warn("Leaderboard element not found.");
}
});
и, наконец, HTML-код для отображения данных:

Код: Выделить всё

Leaderboard
[list][/list]

На данный момент я добавил ведение журнала, переместил различные операторы, включил еще один вызов update_leaderboard() из несвязанной части базы кода (что тоже работает!). Я поместил операторы print(), чтобы отслеживать, что переменные инициализируются, имеют значение и отображаются так, как ожидалось, при отображении.
Я мог бы это понять, если бы вызов update_leaderboard() не дал результата. вообще работает, но я не понимаю, почему он работает только при вызове из некоторых мест кода.

Подробнее здесь: https://stackoverflow.com/questions/792 ... iven-funct
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»