admin管理员组

文章数量:1590342

网页版五子棋对战

1.用户模块

用户的注册和登录

管理用户的天梯分数、比赛场数、获胜场数等信息

2.匹配模块

依据用户的天梯积分,实现匹配机制

3.对战模块

把两个匹配到的玩家放到一个游戏房间中,双方通过网页的形式来进行对战比赛

用到的关键技术点:

Java、Spring/Spring Boot/Spring MVC、HTML/CSS/AJAX、MySQL/MyBatis、WebSocket

我们之前学习过的服务器开发,主要是这样的模型:

客户端主动向服务器发起请求,服务器收到之后,返回一个响应。

如果客户端不主动发起请求,服务器是不能主动联系客户端的

我们是否需要,服务器主动给客户端发消息这样的场景呢?

需要!!“消息推送”

当前已有的知识,主要是HTTP.HTTP自身难以实现这种消息推送效果的

HTTP要想实现类似的效果,就需要基于“轮询”的机制

很明显,像这样的轮询操作,开销是比较大的,成本也是比较高的

如果轮询间隔时间长,玩家1落子之后,玩家2不能及时拿到结果

如果轮询间隔时间短,虽然即使性得到改善,但是玩家2 不得不浪费更多的机器资源(尤其是带宽)

因此,websocket就是一个消息推送机制

websocket报文格式

websocket也是一个应用层的协议,下层是基于TCP的~

opcode描述了当前这个websocket报文是啥类型

表示当前这是一个文本帧还是一个二进制帧

表示当前这是一个ping帧,还是一个pong帧

payload len含义表示的是当前数据报携带的数据载荷的长度。这个字段本身就是一个变长的,一个websocket数据报能承载的载荷长度是非常长的

websocket握手过程(建立连接的过程)

使用网页端,尝试和服务器建立websocket连接

网页端就会先给服务器发起一个HTTP请求 这个HTTP请求中会带有特殊的Header

Connection:Upgrade

Upgrade:Websocket

这两个header其实就是告知服务器,我们要进行协议升级

如果服务器支持websocket,就会返回一个特殊的HTTP响应 这个响应的状态码是101(切换协议)

客户端和服务器之间就开始使用websocket来进行通信了

实现一个简单的websocket代码

编写服务器端(Java)

编写客户端(JS)

通过TestAPI重写了几个类,

光有这几个类还不够 需要把这几个类关联到路径

用户模块

完成注册登录,以及用户分数管理

使用数据库来保存上述用户信息

使用MyBatis来连接并操作数据库

1.修改Spring的配置文件,使数据库可以被连接上(application.yml)

spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/java_gobang?characterEncoding=utf8&useSSL=false
    username: root
    password: zy19991227
    driver-class-name: com.mysql.cj.jdbc.Driver

mybatis:
  mapper-locations: classpath:mapper/**Mapper.xml

2.创建实体类。用户 User

3.创建Mapper接口

针对数据库进行哪些具体的操作

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yvvSwfi5-1688815713045)(C:\Users\zyx\AppData\Roaming\Typora\typora-user-images\image-20230329102600202.png)]

4.实现MyBatis的相关xml配置文件,来自动实现数据库操作

约定前后端交互接口

登录的请求和相应

请求

POST /login HTTP/1.1

Content-Type: application/x-www-form-urlencoded

username=zhangsan&password=123

响应

HTTP/1.1 200 OK
Content-Type: application/json
{
   
​		userId: 1,
​        username:'zhangsan',
​		score: 1000,
​		totalCount: 0,
​		winCount: 0
}

如果登录失败,就返回一个无效的user对象。

如果这里的每个属性都是空的,像userId => 0

注册的请求和相应

请求

POST/register HTTP/1.1

Content-Type: application/x-www-form-urlencoded

username=zhangsan&password=123

响应

HTTP/1.1 200 OK
Content-Type: application/json
{
   
​		userId: 1,
​        username:'zhangsan',
​		score: 1000,
​		totalCount: 0,
​		winCount: 0
}

这个前后端交互的接口,在约定的时候,是有很多种交互方式的

这里约定好了之后,后续的前端或后端代码,都要严格地遵守这个约定来写代码

从服务器获取到当前登录的用户信息的请求和响应

程序运行过程中,用户登陆了之后,让客户端随时通过这个接口,来访问服务器,获取自身的信息

请求

GET/userInfo HTTP/1.1

响应

HTTP/1.1 200 OK
Content-Type: application/json
{
   
​		userId: 1,
​        username:'zhangsan',
​		score: 1000,
​		totalCount: 0,
​		winCount: 0
}

编写服务器代码

package com.example.java_gobang.api;

import com.example.java_gobang.model.User;
import com.example.java_gobang.model.UserMapper;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

@RestController
public class UserAPI {
   

    @Resource
    private UserMapper userMapper;

    @PostMapping("/login")    //请求使用的是POST
    @ResponseBody    //将java对象转为json格式的数据
    public Object login(String username, String password, HttpServletRequest req){
   
        //关键操作:根据username去数据库中进行查询
        //如果能找到匹配的用户,并且密码也一致,就认为登陆成功
        User user = userMapper.selectByName(username);
        System.out.println("[login] user=" + username);
        if(user == null || !user.getPassword().equals(password)){
   
            //登陆失败
            System.out.println("登陆失败");
            return new User();//无效对象
        }
        HttpSession httpSession = req.getSession(true);
        //参数true的含义:会话存在直接返回,会话不存在就创建一个
        //参数false的含义:会话存在直接返回,会话不存在就返回空
        httpSession.setAttribute("user",user);
        return user;
    }

    @PostMapping("/register")
    @ResponseBody
    public Object register(String username,String password){
   
        try {
   
            User user = new User();
            user.setUsername(username);
            user.setPassword(password);
            userMapper.insert(user);
            return user;
        } catch (org.springframework.dao.DuplicateKeyException e){
   
            User user = new User();
            return user;
        }
    }

    @GetMapping("/userInfo")
    @ResponseBody
    public Object getUserInfo(HttpServletRequest req) {
   
        try {
   
            HttpSession httpSession = req.getSession(false);
            User user = (User) httpSession.getAttribute("user");
            return user;
        } catch (NullPointerException e){
   
            return new User();
        }
    }
}

使用Postman测试登录:

用户名和密码都正确

用户名和密码不正确(返回空值)

使用Postman测试注册:

使用Postman测试用户信息:

编写 登录/注册 功能的前端页面

login.html

<!DOCTYPE html>

本文标签: 对战框架五子网页SSM