目录
项目源码:https://github.com/mxzw/Project/tree/main/webgobang-project/src
1. 项目开发背景
小时候,闲来无事最喜欢和别人玩的游戏之一就是五子棋了,它规则简单,但却玩法多变,直到现在我还时不时的在手机上和别人在线对战。最近自己学习Linux方面的相关知识,学习了多线程和Socket编程,并对网络这块的数据流向有了基本的了解,加之刚好找到了一份纯前端的单机五子棋的源码,于是就想尝试能否在该前端的基础上,加上后端,使其变成联机版的网络在线对战五子棋。
由于本人对前端学习并不深入,所有前端的代码都是基于原来现有的前端代码进行的修改。
项目运行截图
用户登录:
用户注册:
下棋页面:
胜利页面:
2.项目需求 & 开发环境
项目需求
- 支持用户登录、用户注册功能
- 支持在线匹配对战功能
- 支持点击重开按钮重新进行匹配功能
- 支持对局信息持久化功能
开发环境
gcc/g++:7.3.1版本,使用C++语言进行开发,并采用MySQL数据库进行相应数据的存储。
项目所用到的相关知识点
多线程,互斥锁和条件变量,httplib,JSON,AJAX,MySQL数据库
3.项目设计 & 项目难点
项目设计
首先,本项目大体的数据流向是前端通过AJAX方法将JSON格式的数据传送到后端,后端通过HttpLib库中的方法获取到前端当中的JSON数据,然后对该数据进行相应逻辑的处理后,将结果返回给前端,前端根据结果显示相应的内容。
项目架构图如下:
项目难点:
- 难点1: 当用户点击开始匹配按钮时,创建房间并为用户分配相应的对手。
- 难点2:在对战过程中,用户只能下一种颜色的棋子(黑棋/白棋),并且只能在属于自己的回合进行下棋。
- 难点3:在对战过程中,对手下的棋子的位置能够及时的同步在自己的棋盘上。
4.功能实现 & 难点解决
由项目设计,我们可以得到本项目大概的框架
- HTTP模块:httplib.h
- 用户管理模块和房间管理模块:room_player.hpp
- 会话模块:Session.hpp
- 数据库管理模块:ManagerDB.hpp
- 工具模块:tools.hpp
- 项目驱动模块:webgobang.hpp、webgobang.cpp
4.1. 用户登录 / 注册
当用户在网页上点击登录按钮的时候,前端会对用户输入的邮箱和密码进行获取,将数据转为JSON格式(序列化),并通过AJAX,采用POST的http请求方法将该数据发送到后端去,后端校验该数据之后,将其持久化到数据库中,并且根据输入的邮箱和密码生成相应的MD5码作为当前用户的cookie信息返回回去。
登录页面后端代码如下:
http_svr_.Post("/login", [=](const Request& req, Response& res) {
//1.校验用户(登录页面)所提交的邮箱和密码(与数据库进行比较)
cout << req.body << endl;
Json::Reader r;
Json::Value v; //存储string :string 的键值对
r.parse(req.body, v); // 用于将请求正文中的内容反序列化(从连续的二进制转为对应键值对)
//cout <<"v[\"email\"]" <<v["email"] << endl;
//cout <<"v[\"password\"]" <<v["password"] << endl;
//
// 1.1 同数据库进行校验并得到对应user_id
int user_id = this->db_svr_->CheckUserExist(v);
//1.2 为了防止用户不经过登录,直接访问主页面,我们需要在这里加上一个session会话
// 设置MD5码,作为会话id 进行http响应
string tmp = "";
if (user_id > 0)
{
Session sess(v, user_id);
string session_id = sess.GetSessionID();
//回复的会话格式为JSESSIONID = xxxxx
tmp += "JSESSIONID=" + session_id;
all_sess_->SetSessionInfo(session_id, sess);
//将该用户放到用户管理类中进行管理
this->pm_->insertPlayer2Map(user_id);
}
//2.组织http响应格式使用校验的结果进行响应(使用Json对其进行响应,因为ajax中接收的数据类型为json)
Json::Value res_value;
// 在前端ajax请求中,要求接收的是一个Json对象,并且该对象中含有status的键值对
res_value["status"] = user_id >= 0 ? true : false;
//将该Json-Value对象序列化 并进行响应
res