You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Tomcat 10.1中WebSocket频繁关闭且onMessage方法不触发问题求助

问题描述

我正在开发基于Tomcat 10.1服务器的WebSocket+Servlet游戏应用,目标是创建房主制本地实时游戏——将“localhost”替换为房主的IPv4,就能让其他玩家实时加入。但目前遇到两个问题:

  • WebSocket连接总是自动关闭
  • WebSocket类中的onMessage方法从未触发,哪怕客户端已经发送消息

lobby.jsp(包含创建和加入按钮)

<body> Bienvenue, <%= username %>! Choisissez une option pour continuer :
<form action="createGameSocket" method="POST" style="display:inline;">
    <button type="submit" class="button">Create Game</button>
</form>

<button onclick="joinGame(event)" class="button">Join Game</button>

<script>
function joinGame(event) {
    event.preventDefault();
    window.location.href = "joinGame.jsp";
}
</script>

点击“Create Game”按钮后会调用CreateGameServlet:

CreateGameServlet.java

package controller;

import jakarta.servlet.ServletException; 
import jakarta.servlet.annotation.WebServlet; 
import jakarta.servlet.http.HttpServlet; 
import jakarta.servlet.http.HttpServletRequest; 
import jakarta.servlet.http.HttpServletResponse; 
import jakarta.servlet.http.HttpSession;

import java.io.IOException; 
import java.sql.Connection; 
import java.sql.DriverManager; 
import java.sql.PreparedStatement;

@WebServlet("/createGameSocket") 
public class CreateGameServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        HttpSession session = request.getSession();
        String username = (String) session.getAttribute("username");

        if (username == null) {
            response.sendRedirect("index.jsp");
            return;
        }

        String gameCode = java.util.UUID.randomUUID().toString().substring(0, 6).toUpperCase();
        session.setAttribute("gameCode", gameCode);
        System.out.println("Voici le gameCode : " + gameCode);

        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/game_db", "root", "test");

            String insertQuery = "INSERT INTO games (host_player_id, code, status) VALUES (?, ?, ?)";
            PreparedStatement stmt = conn.prepareStatement(insertQuery);

            int hostPlayerId = 1; // 后续需修改为获取当前登录用户的真实ID
            stmt.setInt(1, hostPlayerId);
            stmt.setString(2, gameCode);
            stmt.setString(3, "waiting");
            stmt.executeUpdate();

            stmt.close();
            conn.close();

            response.sendRedirect("createGame.jsp?code=" + gameCode);
        } catch (Exception e) {
            e.printStackTrace();
            response.getWriter().println("Erreur lors de la création de la partie : " + e.getMessage());
        }
    }
}

该Servlet会跳转至createGame.jsp:

createGame.jsp

<!DOCTYPE html>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<title>Créer une partie</title>
<h1>Partie créée avec succès</h1>
<p>Attendez que les joueurs se connectent, puis démarrez la partie.</p>

<form action="startGame.jsp" method="POST">
    <button type="submit" class="button">Démarrer la partie</button>
</form>

<h1>Partie créée avec succès</h1>
<p>Donnez ces informations aux joueurs pour qu'ils se connectent :</p>
<p class="info" >Adresse IPv4 : 192.168.56.1</p>
<p class="info" >Code de la partie : <%= request.getParameter("code") %></p>
<p class="info" >Joueurs connectés : <span id="players"></span></p>

<script>
    const gameCode = "<%= request.getParameter("code") %>";
    const socket = new WebSocket("ws://192.168.56.1:8080/gameSocket");

    socket.onopen = () => {
        console.log("Connexion WebSocket ouverte");
        socket.send(JSON.stringify({ type: "host", gameCode: gameCode }));
    };

    socket.onmessage = (event) => {
        console.log("Message reçu : ", event.data);
        const data = JSON.parse(event.data);
        if (data.message) {
            document.getElementById("players").textContent = data.message;
        }
    };

    socket.onerror = (error) => {
        console.error("Erreur WebSocket : ", error);
    };

    socket.onclose = () => {
        console.log("Connexion WebSocket fermée");
    };

    function startGame() {
        console.log("Partie démarrée !");
        
    }
</script>

附web.xml配置:

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd" 
         version="5.0">
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>default.html</welcome-file>
        <welcome-file>default.jsp</welcome-file>
        <welcome-file>default.htm</welcome-file>
    </welcome-file-list>
</web-app>

内容的提问来源于stack exchange,提问作者samuel silva

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 03:27:07