当前位置: 首页 > news >正文

[网页五子棋][匹配模块]前后端交互接口(消息推送机制)、客户端开发(匹配页面、匹配功能)

让多个用户,在游戏大厅中能够进行匹配,系统会把实力相近的两个玩家凑成一桌,进行对战

约定前后端交互接口

消息推送机制

匹配这样的功能,也是依赖消息推送机制的

image.png

  • 玩家 1 点击开始匹配按钮,就会告诉服务器:我要开始进行匹配
  • 玩家发送匹配请求,这个事情是确定(点击了匹配按钮,就会发送匹配请求),服务器什么时候告知玩家匹配结果(你到你排到了谁),就需要等待匹配结束的时候才能告知
  • 正是因为服务器自己也不确定,什么时候能告知玩家匹配的结果,因此就需要依赖消息推送机制
    • 当服务器这里匹配成功之后,就主动的告诉当前排到的所有玩家,“你排到了”

这里就需要用到消息推送机制,也就是需要用到 websocket

  • 接下来约定和前后端交互接口,也都是基于 websocket 来展开的
  • 和前面的 HTTP 还是有点区别的

交互接口约定

websocket 可以传输文本数据,也能传输二进制数据。此处就直接设计成让 websocket 传输 JSON 格式的文本数据即可

匹配请求

  • 客户端通过 websocket 给服务器发送一个 JSON 格式的文本数据
    • ws://127.0.0.1:8080/findMatch
      {
      message: 'startMarch' / 'stopMatch' // 开始匹配/结束匹配
      }

在通过 websocket 传输请求数据的时候,数据中是不必带有用户身份信息的,当前用户的身份信息,在前面登录完成后,就已经保存到 HttpSession 中了。websocket 里,也是能拿到之前登录好的 HttpSession 中的信息的

匹配响应 1

ws://127.0.0.1:8080/Match
{
ok: true, // 匹配成功
reason: ‘’, // 匹配如果失败,失败原因的信息
message: ‘startMatch’ / ‘stopMatch’,
}

这个响应,是客户端给服务器发送请求之后,服务器立即返回的匹配响应

匹配响应 2

ws://127.0.0.1:8080/findMatch
{
ok: true.
reason: ‘’,
message: ‘matchSuccess’
}

这个响应是真正匹配到对手之后,服务器主动推送回来的信息

  • 匹配到的对手不需要在这个响应中体现,仍然都放到服务器这边来保存即可

客户端开发

匹配页面

image.png|508

game_hall. html

创建 game_hall. html,主要包含

  • #screen 用于显示玩家的分数信息
  • button#match-button 作为匹配按钮
<!DOCTYPE html>  
<html lang="en">  
<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/game_hall.css">  
</head>  
<body>  <div class="nav">五子棋对战</div>  <!-- 整个页面的容器元素 -->  <div class="container">  <!-- 这个 div 在 container 中是处于垂直水平居中这样的位置 -->  <div>  <!-- 展示用户信息 -->  <div id="screen"></div>  <!-- 匹配按钮 -->  <div id="match-button">开始匹配</div>  </div>    </div>    <script src="js/jquery.min.js"></script>  <script>        $.ajax({  type: 'get',  url: '/userInfo',  success: function(body) {  // 将 user 对喜爱那个添加到页面的显示内容中  let screenDiv = document.querySelector("#screen");  screenDiv.innerHTML = '玩家: ' + body.username + '分数: ' + body.score  + "<br> 比赛场次: " + body.totalCount + "获胜场次: " + body.winCount;  },  error: function() {  alert("获取用户信息失败!")  }  })  </script>  
</body>  
</html>

game_hall.css

.container {  width: 100%;  height: calc(100% - 50px);  display: flex;  align-items: center;    justify-content: center;  
}  #screen {  width: 400px;  height: 200px;  font-size: 20px;  background-color: gray;  color: white;  border-radius: 10px;  text-align: center;  line-height: 100px;  
}  #match-button {  width: 400px;  height: 50px;  font-size: 20px;  color: white;  background-color: orange;  border: none;  outline: none;  border-radius: 10px;  text-align: center;  line-height: 50px;  margin-top: 20px;  
}  #match-button:active {  background-color: gray;  
}

image.png|233

  • 当我们修改了 css 样式/ JS 文件之后,往往要在浏览器中使用 cmd+shift+R(Windows:ctrl+f5)强制刷新,才能生效
  • 否则浏览器可能仍然在执行旧版本的代码(浏览器自带缓存)

匹配功能

编辑 game_hall.htmljs 部分代码

  • 点击匹配按钮,就会进入匹配逻辑,同时按钮上提示“匹配中...(点击取消)”字样
  • 再次点击匹配按钮,则会取消匹配
  • 当匹配成功后,服务器会返回匹配成功的响应,页面跳转到 game_room.html
<!DOCTYPE html>  
<html lang="en">  
<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/game_hall.css">  
</head>  
<body>  <div class="nav">五子棋对战</div>  <!-- 整个页面的容器元素 -->  <div class="container">  <!-- 这个 div 在 container 中是处于垂直水平居中这样的位置 -->  <div>  <!-- 展示用户信息 -->  <div id="screen"></div>  <!-- 匹配按钮 -->  <div id="match-button">开始匹配</div>  </div>    </div>    <script src="js/jquery.min.js"></script>  <script>        $.ajax({  type: 'get',  url: '/userInfo',  success: function(body) {  // 将 user 对喜爱那个添加到页面的显示内容中  let screenDiv = document.querySelector("#screen");  screenDiv.innerHTML = '玩家: ' + body.username + '分数: ' + body.score  + "<br> 比赛场次: " + body.totalCount + "获胜场次: " + body.winCount;  },  error: function() {  alert("获取用户信息失败!")  }  });  // 此处进行初始化 websocket,并且实现前端匹配逻辑  // 此处的路径必须写作 /findMatch,千万不要写作 /findMatch/        let websocket = new websocket('ws://127.0.0.1:8080/findMatch');  websocket.onopen = function() {  console.log("onopen");  }  websocket.onclose = function() {  console.log("onclose");  }  websocket.onerror = function() {  console.log("onerror");  }  // 监听页面关闭事件,在页面关闭之前,手动调用这里 websocket 的 close 方法  window.onbeforeunload = function() {  websocket.close();  }  // 一会重点来实现,要处理服务器返回的响应  websocket.onmessage = function(e) {  // 处理服务器返回的响应数据,这个响应就是针对“开始匹配”/“结束匹配”来对应的  // 解析得到的响应对象,返回的数据是一个 JSON 字符串,解析成 js 对象  let resp = JSON.parse(e.data);  let match-button = document.querySelector('#match-button');  if (!resp.ok) {  console.log("游戏大厅中接收到了失败响应!" + resp.reason);  return;  }  if (resp.message == 'startMatch') {  // 开始匹配请求发送成功  console.log("进入匹配队列成功!");  matchButton.innerHTML = '匹配中...(点击停止)';  }else if(resp.message == 'stopMatch') {  // 结束匹配请求发送成功  console.log("离开匹配队列成功!");  matchButton.innerHTML = '开始匹配';  }else if(resp.message == 'matchSuccess') {  // 已经匹配到对手了  console.log("匹配到对手! 进入游戏房间!");  location.assign('/game_room.html');  }else {  console.log("收到了非法的响应! message=" + resp.message);  }  }  // 给匹配按钮添加一个点击事件  let matchButton = document.querySelector('#match-button');  matchButton.onclick - function() {  // 在触发 websocket 请求之前,先确认下 websocket 连接是否好着  if (websocket.readyState == websocket.OPEN) {  // 如果当前 redyState 处于 OPEN 状态,说明连接好着的  // 这里发送的数据有两种可能,开始匹配/停止匹配  if (matchButton.innerHTML == '开始匹配') {  console.log("开始匹配");  websocket.send(JSON.stringify({  message: 'startMatch',  }));  } else if (matchButton.innerHTML == '匹配中...(点击停止)') {  console.log("停止匹配");  websocket.send(JSON.stringify({  message: 'stopMatch',  }));  }  }else {  // 这是说明连接当前是异常状态  alert("当前您的连接已经断开!请重新登录!");  location.assign('/login.html');  }  }  </script>  
</body>  
</html>
  • 此部分主要逻辑从 36 行开始

JSON 字符串和 JS 对象的转换

  • JSON 字符串转换成 JS 对象:JSON.pares
  • JS 对象转换成 JSON 对象:JSON.stringify

JSON 字符串和 Java 对象的转换

  • JSON 字符串转换成 Java 对象:ObjectMapper.readValue
  • Java 对象转成 JSON 字符串:ObjectMapper.writeValueAsString

相关文章:

  • Android学习之定时任务
  • 大数据-273 Spark MLib - 基础介绍 机器学习算法 决策树 分类原则 分类原理 基尼系数 熵
  • 深入解析Linux死锁:原理、原因及解决方案
  • 《ChatGPT o3抗命:AI失控警钟还是成长阵痛?》
  • 基于对比学习的推荐系统开发方案,使用Python在PyCharm中实现
  • Transformer架构详解:从Attention到ChatGPT
  • Senna代码解读
  • spring sentinel
  • Linux `vi/vim` 编辑器深度解析与高阶应用指南
  • (25年5.28)ChatGPT Plus充值教程与实用指南:附国内外使用案例与模型排行
  • Service Worker介绍及应用(实现Web Push机制)
  • 华为AP6050DN无线接入点瘦模式转胖模式
  • 【数据结构初阶】顺序表的应用
  • PostgreSQL 内置扩展列表
  • 嵌入式通用集成电路卡市场潜力报告:物联网浪潮下的机遇与挑战剖析
  • Parasoft C++Test软件单元测试_实例讲解(对多次调用的函数打桩)
  • Java复习Day21
  • 常用 Linux 命令---服务器开发和运维相关命令
  • JAVA网络编程——socket套接字的介绍下(详细)
  • 互联网大厂Java求职面试:AI与云原生架构实战解析
  • 单页网站seo优化/市场调研方案范文
  • 哪家公司做网站好/苏州seo培训
  • 北京 网站 外包/百度发布信息的免费平台
  • 做网站前台后台是怎么连接的/优化关键词排名优化公司
  • 网站管理的内容包括/seo优化流程
  • 百度信息流/百度seo引流