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

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

1. 页面实现

hall.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

.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代码从访问后端接口获取信息:

    <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

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方法,进入匹配状态,此时我们可以把开始匹配按钮替换成取消匹配按钮,再次点击则会向服务器发送取消匹配请求。

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表示请求成功

//处理服务器发送的消息
        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子类,重写如下方法: 

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:
 

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());
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/957038.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

网络安全VS数据安全

关于网络安全和数据安全&#xff0c;我们常听到如下两种不同声音&#xff1a; 观点一&#xff1a;网络安全是数据安全的基础&#xff0c;把当年做网络安全的那一套用数据安全再做一遍。 观点二&#xff1a;数据安全如今普遍以为是网络安全的延伸&#xff0c;实际情况是忽略数据…

React 中hooks之useDeferredValue用法总结

目录 概述基本用法与防抖节流的区别使用场景区分过时内容最佳实践 概述 什么是 useDeferredValue? useDeferredValue 是 React 18 引入的新 Hook&#xff0c;用于延迟更新某个不那么重要的部分。它接收一个值并返回该值的新副本&#xff0c;新副本会延迟更新。这种延迟是有…

浅谈 JVM

JVM 内存划分 JVM 内存划分为 四个区域&#xff0c;分别为 程序计数器、元数据区、栈、堆 程序计数器是记录当前指令执行到哪个地址 元数据区存储存储的是当前类加载好的数据&#xff0c;包括常量池和类对象的信息&#xff0c;.java 编译之后产生 .class 文件&#xff0c;运…

HTTP / 2

序言 在之前的文章中我们介绍过了 HTTP/1.1 协议&#xff0c;现在再来认识一下迭代版本 2。了解比起 1.1 版本&#xff0c;后面的版本改进在哪里&#xff0c;特点在哪里&#xff1f;话不多说&#xff0c;开始吧⭐️&#xff01; 一、 HTTP / 1.1 存在的问题 很多时候新的版本的…

使用vscode在本地和远程服务器端运行和调试Python程序的方法总结

1 官网下载 下载网址&#xff1a;https://code.visualstudio.com/Download 如下图所示&#xff0c;可以分别下载Windows,Linux,macOS版本 历史版本下载链接: https://code.visualstudio.com/updates 2 安装Python扩展工具 打开 VS Code&#xff0c;安装 Microsoft 提供的官…

免费为企业IT规划WSUS:Windows Server 更新服务 (WSUS) 之快速入门教程(一)

哈喽大家好&#xff0c;欢迎来到虚拟化时代君&#xff08;XNHCYL&#xff09;&#xff0c;收不到通知请将我点击星标&#xff01;“ 大家好&#xff0c;我是虚拟化时代君&#xff0c;一位潜心于互联网的技术宅男。这里每天为你分享各种你感兴趣的技术、教程、软件、资源、福利…

Ubuntu 24.04 LTS 安装 tailscale 并访问 SMB共享文件夹

Ubuntu 24.04 LTS 安装 tailscale 安装 Tailscale 官方仓库 首先&#xff0c;确保系统包列表是最新的&#xff1a; sudo apt update接下来&#xff0c;安装 Tailscale 所需的仓库和密钥&#xff1a; curl -fsSL https://tailscale.com/install.sh | sh这会自动下载并安装 …

基于python+Django+mysql鲜花水果销售商城网站系统设计与实现

博主介绍&#xff1a;黄菊华老师《Vue.js入门与商城开发实战》《微信小程序商城开发》图书作者&#xff0c;CSDN博客专家&#xff0c;在线教育专家&#xff0c;CSDN钻石讲师&#xff1b;专注大学生毕业设计教育、辅导。 所有项目都配有从入门到精通的基础知识视频课程&#xff…

“AI人工智能内容辅助创作平台:让创意不再“卡壳”

在如今这个信息爆炸的时代&#xff0c;内容创作成了每个人的“必修课”。无论是自媒体大V、文案策划&#xff0c;还是普通学生写作文&#xff0c;大家都会遇到一个让人抓狂的问题——“创意枯竭”。有时候&#xff0c;脑袋里空空如也&#xff0c;一个字都写不出来&#xff0c;那…

【计算机网络】传输层协议TCP与UDP

传输层 传输层位于OSI七层网络模型的第四层&#xff0c;主要负责端到端通信&#xff0c;可靠性保障&#xff08;TCP&#xff09;&#xff0c;流量控制(TCP)&#xff0c;拥塞控制(TCP)&#xff0c;数据分段与分组&#xff0c;多路复用与解复用等&#xff0c;通过TCP与UDP协议实现…

基础入门-传输加密数据格式编码算法密文存储代码混淆逆向保护安全影响

知识点&#xff1a; 1、传输格式&传输数据-类型&编码&算法 2、密码存储&代码混淆-不可逆&非对称性 一、演示案例-传输格式&传输数据-类型&编码&算法 传输格式 JSON XML WebSockets HTML 二进制 自定义 WebSockets&#xff1a;聊天交互较常…

DenseNet-密集连接卷积网络

DenseNet&#xff08;Densely Connected Convolutional Network&#xff09;是近年来图像识别领域中一种创新且高效的深度卷积神经网络架构。它通过引入密集连接的设计&#xff0c;极大地提高了特征传递效率&#xff0c;减缓了梯度消失问题&#xff0c;促进了特征重用&#xff…

记一次数据库连接 bug

整个的报错如下&#xff1a; com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Could not create connection to database server. Attempted reconnect 3 times. Giving up. at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Metho…

Docker:基于自制openjdk8镜像 or 官方openjdk8镜像,制作tomcat镜像

一、制作openjdk8基础镜像【基于自定义alpine-3.18.0:v1 】 docker pull maven:3.5.0-jdk-8-alpine 78.56 MB https://hub.docker.com/_/maven/tagspage8&namealpine openjdk二进制下载地址 https://blog.csdn.net/fenglllle/article/details/124786948 https://adoptope…

vue 入门到实战 一

目录 第1章 初始Vue.js 1.1 网站交互方式 1.2 MVVM模式 1.3 Vue.js是什么 1.4 安装Vue.js 1.5 第一个Vue.js程序 1.6 插值与表达式 第1章 初始Vue.js 1.1 网站交互方式 Web网站有单页应用程序&#xff08;SPA&#xff0c;Single-page Application&#xff09;和多页应用…

【2024 年度总结】从小白慢慢成长

【2024 年度总结】从小白慢慢成长 1. 加入 CSDN 的契机2. 学习过程2.1 万事开头难2.2 下定决心开始学习2.3 融入技术圈2.4 完成万粉的目标 3. 经验分享3.1 工具的选择3.2 如何提升文章质量3.3 学会善用 AI 工具 4. 保持初心&#xff0c;继续前行 1. 加入 CSDN 的契机 首次接触…

Apache SeaTunnel 2.3.9 正式发布:多项新特性与优化全面提升数据集成能力

近日&#xff0c;Apache SeaTunnel 社区正式发布了最新版本 2.3.9。本次更新新增了Helm 集群部署、Transform 支持多表、Zeta新API、表结构转换、任务提交队列、分库分表合并、列转多行 等多个功能更新&#xff01; 作为一款开源、分布式的数据集成平台&#xff0c;本次版本通过…

mybatis的多对一、一对多的用法

目录 1、使用VO聚合对象&#xff08;可以解决这两种情况&#xff09; 多对一&#xff1a; 一对多&#xff1a; 2、非聚合的多对一做法&#xff1a; 3、非聚合的一对多做法&#xff1a; 1、使用VO聚合对象&#xff08;可以解决这两种情况&#xff09; 当我需要多对一、一对…

SpringCloud系列教程:微服务的未来(十四)网关登录校验、自定义过滤器GlobalFilter、GatawayFilter

前言 在微服务架构中&#xff0c;API 网关扮演着至关重要的角色&#xff0c;负责路由请求、执行安全验证、流量控制等任务。Spring Cloud Gateway 作为一个强大的网关解决方案&#xff0c;提供了灵活的方式来实现这些功能。 本篇博客将重点介绍如何在 Spring Cloud Gateway 中…

服务化架构 IM 系统之应用 MQ

在微服务化系统中&#xff0c;存在三个最核心的组件&#xff0c;分别是 RPC、注册中心和MQ。 在前面的两篇文章&#xff08;见《服务化架构 IM 系统之应用 RPC》和《服务化架构 IM 系统之应用注册中心》&#xff09;中&#xff0c;我们站在应用的视角分析了普适性的 RPC 和 注…