项目实战--网页五子棋(游戏大厅)(3)

我们的游戏大厅界面主要需要包含两个功能,一是显示用户信息,二是匹配游戏按钮

1. 页面实现

hall.html

html 复制代码
<!DOCTYPE html>
<html lang="ch">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>游戏大厅</title>
    <link rel="stylesheet" href="css/common.css">
    <link rel="stylesheet" href="css/hall.css">
</head>
<body>
    <div class="nav">五子棋</div>
    <div class="container">
        <div class="dialog">
            <!-- 展示用户信息 -->
            <div id="screen"></div>
            <!-- 开始匹配 -->
            <button id="match" onclick="findMatch()">开始匹配</button>
        </div>
    </div>
</body>
</html>

hall.css

css 复制代码
.container {
    height: calc(100% - 50px);
    display: flex;
    justify-content: center;
    align-items: center;
}

.container .dialog {
    height: 350px;
    width: 299px;
    background-color: white;
    border-radius: 20px;
    padding-top: 30px;
    display: flex;
    justify-content: center;
    /* align-items: center; */
    flex-wrap: wrap
}

.dialog *{
    display: flex;
    justify-content: center;
    align-items: center;
}

.dialog #screen {
    width: 250px;
    height: 150px;
    background-color: wheat;
    border-radius: 10px;
}

.dialog #match {
    width: 150px;
    height: 40px;
    background-color: rgb(255, 159, 33);
    border-radius: 10px;
}

.dialog #match:active {
    background-color: rgb(204, 128, 21);
}

2. 获取用户信息接口

当用户进入 游戏大厅时,就应该获取到登录用户的信息显示到页面上,我们使用js代码从访问后端接口获取信息:

html 复制代码
    <script src="js/jquery.min.js"></script>
    <script>
        $.ajax({
            type: 'post',
            url: '/user/getLoginUser',
            success: function(result) {
                if(result.username != null) {
                    let screen = document.querySelector("#screen");
                    screen.innerHTML = '当前玩家:' + result.username + '<br>天梯积分:' + 
                    result.score + '<br>比赛场次:' + result.totalCount + 
                    '<br>获胜场次:' + result.winCount;
                }else{
                    alert("获取用户信息失败,请重新登录");
                    location.href = "/login.html";
                }
            },
            error: function() {
                alert("获取用户信息失败");
            }
        });
    </script>

运行效果:

2. WebSocket前端代码

当用户点击匹配按钮时,需要告知服务器该用户要进行匹配,服务器如果接收到则立即回复表示正在匹配,当匹配成功服务器则又需要发送匹配信息给客户端。这里涉及到服务器主动给客户端发送消息的场景,所以我们使用websocket实现

2.1 初始化websocket

javascript 复制代码
let webSocket = new WebSocket('ws://127.0.0.1:8080/findMatch');
        webSocket.onopen = function() {
            console.log("连接成功");
        }
        webSocket.onclose = function() {
            console.log("连接关闭");
        }
        webSocket.onerror = function() {
            console.log("error");
        }

        //页面关闭时释放webSocket
        window.onbeforeunload = function() {
            webSocket.close();
        }

        //处理服务器发送的消息
        webSocket.onmessage = function(e) {

        }

        function findMatch() {
            //检查websocket连接
            if(webSocket.readyState == webSocket.OPEN) {

            }else{
                alert("连接断开,请重新登录");
                location.href = "/login.html";
            }
        }

2.2 实现findMatch()方法

点击开始匹配按钮后就会执行findMatch方法,进入匹配状态,此时我们可以把开始匹配按钮替换成取消匹配按钮,再次点击则会向服务器发送取消匹配请求。

javascript 复制代码
function findMatch() {
            //检查websocket连接
            if(webSocket.readyState == webSocket.OPEN) {
                if($("#match").text() == '开始匹配') {
                    console.log("开始匹配");
                    webSocket.send(JSON.stringify({
                        message: 'startMatch' //约定startMatch表示开始匹配
                    }));
                }else if($("#match").text() == '匹配中...') {
                    console.log("停止匹配");
                    webSocket.send(JSON.stringify({
                        message: 'stopMatch' //约定stopMatch表示停止匹配
                    }));
                }
            }else{
                alert("连接断开,请重新登录");
                location.href = "/login.html";
            }
        }

2.3 实现onmessage

我们约定服务器返回的响应为包含以下三个字段的json:

  • ok: true/false, //表示请求成功还是失败
  • errMsg:"错误信息", //请求失败返回错误信息
  • message: 'startMatch' / 'stopMatch' / 'success' //success表示请求成功
javascript 复制代码
//处理服务器发送的消息
        webSocket.onmessage = function(e) {
            //解析json字符串为js对象
            let resp = JSON.parse(e.data);
            if(!resp.ok) {
                console.log(resp.errMsg);
                return;
            }
            if(resp.message == 'startMatch') {
                //开始匹配请求发送成功正在匹配
                //替换按钮描述
                $("#match").text("匹配中...");
            }else if(resp.message == 'stopMatch') {
                //取消匹配请求发送成功已取消匹配
                //替换按钮描述
                $("#match").text("开始匹配");
            }else if(resp.message == 'success'){
                //匹配成功
                console.log("匹配成功! 进入游戏房间");
                locating.href = "/game.html";
            }else{
                console.log("非法响应 errMsg:" + resp.errMsg);
                
            }

        }

3. WebSocket后端代码

3.1 注册websocket

创建TextWebSocketHandler子类,重写如下方法:

javascript 复制代码
package org.ting.j20250110_gobang.websocket;

import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

@Component
public class MatchWebSocket extends TextWebSocketHandler {
    //连接成功后执行
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        super.afterConnectionEstablished(session);
    }
    //接收到请求后执行
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        super.handleTextMessage(session, message);
    }
    //连接异常时执行
    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        super.handleTransportError(session, exception);
    }
    //连接正常断开后执行
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        super.afterConnectionClosed(session, status);
    }
}

注册socket:

java 复制代码
package org.ting.j20250110_gobang.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;
import org.ting.j20250110_gobang.websocket.MatchWebSocket;
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
    @Autowired
    MatchWebSocket matchWebSocket;
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(matchWebSocket, "/findMatch") //注意路径和前端对应
                //添加拦截器获取到session,方便获取session中的用户信息
                .addInterceptors(new HttpSessionHandshakeInterceptor());
    }
}
相关推荐
kill bert8 分钟前
第30周Java分布式入门 消息队列 RabbitMQ
java·分布式·java-rabbitmq
穿林鸟1 小时前
Spring Boot项目信创国产化适配指南
java·spring boot·后端
此木|西贝1 小时前
【设计模式】模板方法模式
java·设计模式·模板方法模式
wapicn992 小时前
手机归属地查询Api接口,数据准确可靠
java·python·智能手机·php
hycccccch2 小时前
Springcache+xxljob实现定时刷新缓存
java·后端·spring·缓存
wisdom_zhe2 小时前
Spring Boot 日志 配置 SLF4J 和 Logback
java·spring boot·logback
揣晓丹2 小时前
JAVA实战开源项目:校园失物招领系统(Vue+SpringBoot) 附源码
java·开发语言·vue.js·spring boot·开源
于过3 小时前
Spring注解编程模型
java·后端
北随琛烬入3 小时前
Spark(10)配置Hadoop集群-集群配置
java·hadoop·spark
顽疲3 小时前
从零用java实现 小红书 springboot vue uniapp (11)集成AI聊天机器人
java·vue.js·spring boot·ai