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

基于websocket的多用户网页五子棋(八)

一.前期回顾

对于前面内容不太了解的,可以去看一看下面的文章:

https://blog.csdn.net/weixin_60668256/article/details/152661096?fromshare=blogdetail&sharetype=blogdetail&sharerId=152661096&sharerefer=PC&sharesource=weixin_60668256&sharefrom=from_link

二.游戏大厅长连接的建立

void wsopen_callback(websocketpp::connection_hdl hdl){}
void ws_resp(wsserver_t::connection_ptr conn,Json::Value& resp){std::string body;json_util::serialize(resp,body);conn->send(body);}void weopen_game_hall(wsserver_t::connection_ptr conn){//游戏大厅长连接建立成功//1.登录验证 -- 判断当前客户端是否以及成功登录Json::Value err_resp;std::string cookie_str = conn->get_request_header("Cookie");if(cookie_str.empty()){err_resp["optype"] = "hall_ready";err_resp["reason"] = "找不到cookie信息,请重新登录";err_resp["result"] = false;return ws_resp(conn,err_resp);}std::string ssid_str;bool ret = get_cookie_val(cookie_str,"SSID",ssid_str);if(ret == false){err_resp["optype"] = "hall_ready";err_resp["reason"] = "找不到ssid信息,请重新登录";err_resp["result"] = false;return ws_resp(conn,err_resp);}session_ptr ssp = _sm.get_session_by_ssid(std::stol(ssid_str));if(ssp.get() == nullptr){err_resp["optype"] = "hall_ready";err_resp["reason"] = "找不到session信息,请重新登录";err_resp["result"] = false;return ws_resp(conn,err_resp);}//2.判定当前客户端是否重复登录if(_om.is_in_game_hall(ssp->get_user()) || _om.is_in_game_hall(ssp->get_user())){err_resp["optype"] = "hall_ready";err_resp["reason"] = "玩家重复登录!";err_resp["result"] = false;return ws_resp(conn,err_resp);}//3.将当前客户端以及连接加入到游戏大厅_om.enter_game_hall(ssp->get_user(),conn);//4.给客户端响应长连接的游戏大厅连接成功Json::Value resp_json;resp_json["optype"] = "hall_ready";resp_json["result"] = true;ws_resp(conn,resp_json);//5.记得将session设置为永久存在_sm.set_session_expire_time(ssp->ssid(),SESSION_FOREVER);}void weopen_game_room(wsserver_t::connection_ptr conn){}void wsopen_callback(websocketpp::connection_hdl hdl){//websocket长连接建立成功的回调函数wsserver_t::connection_ptr conn = _wssrv.get_con_from_hdl(hdl);websocketpp::http::parser::request req = conn->get_request();std::string uri = req.get_uri();if(uri == "/hall"){//建立游戏大厅的长连接return weopen_game_hall(conn);}else if(uri == "/room"){//建立游戏房间的长连接return weopen_game_room(conn);}}
function get_user_info() {$.ajax({url: "/info",type: "get",success: function(res) {var info_html = "<p>" + "用户:" + res.username + " 积分:" + res.score + "</br>" + "比赛场次:" + res.total_count + " 获胜场次:" + res.win_count + "</p>";var screen_div = document.getElementById("screen");screen_div.innerHTML = info_html;ws_hdl = new WebSocket(ws_url);ws_hdl.onopen = ws_onopen;ws_hdl.onclose = ws_onclose;ws_hdl.onerror = ws_onerror;ws_hdl.onmessage = ws_onmessage;},error: function(xhr) {alert(JSON.stringify(xhr));location.replace("/login.html");}})}function ws_onopen() {console.log("websocket onopen");}function ws_onclose() {console.log("websocket onclose");}function ws_onerror() {console.log("websocket onerror");}

目前还没有实现游戏房间内的长连接,我们先进行长连接移除的函数实现

三.游戏大厅长连接的删除

void wsclose_game_hall(wsserver_t::connection_ptr conn){//游戏大厅的长连接断开Json::Value err_resp;std::string cookie_str = conn->get_request_header("Cookie");if(cookie_str.empty()){err_resp["optype"] = "hall_ready";err_resp["reason"] = "找不到cookie信息,请重新登录";err_resp["result"] = false;return ws_resp(conn,err_resp);}std::string ssid_str;bool ret = get_cookie_val(cookie_str,"SSID",ssid_str);if(ret == false){err_resp["optype"] = "hall_ready";err_resp["reason"] = "找不到ssid信息,请重新登录";err_resp["result"] = false;return ws_resp(conn,err_resp);}session_ptr ssp = _sm.get_session_by_ssid(std::stol(ssid_str));if(ssp.get() == nullptr){err_resp["optype"] = "hall_ready";err_resp["reason"] = "找不到session信息,请重新登录";err_resp["result"] = false;return ws_resp(conn,err_resp);}//1.将玩家从游戏大厅移除_om.exit_game_hall(ssp->get_user());//2.将session恢复生命周期的管理_sm.set_session_expire_time(ssp->ssid(),SESSION_TIMEOUT);}void wsclose_game_room(wsserver_t::connection_ptr conn){//游戏房间的长连接断开}void wsclose_callback(websocketpp::connection_hdl hdl){//1.websocket连接断开前的处理wsserver_t::connection_ptr conn = _wssrv.get_con_from_hdl(hdl);websocketpp::http::parser::request req = conn->get_request();std::string uri = req.get_uri();if(uri == "/hall"){//游戏大厅的长连接断开return wsclose_game_hall(conn);}else if(uri == "/room"){//游戏房间的长连接断开return wsclose_game_room(conn);}}
window.onbeforeunload = function() {ws_hdl.close();}

房间内同样还是没有进行完成

四.游戏大厅内消息处理

实现按钮点击发送消息到后台服务器

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><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>var ws_url = "ws://" + location.host + "/hall";var ws_hdl = null;window.onbeforeunload = function() {ws_hdl.close();}//按钮有两个状态:没有进行匹配的状态,正在匹配中的状态var button_flag = "stop";//点击按钮的事件处理:var be = document.getElementById("match-button");be.onclick = function() {if (button_flag == "stop") {//1. 没有进行匹配的状态下点击按钮,发送对战匹配请求var req_json = {optype: "match_start"}ws_hdl.send(JSON.stringify(req_json));}else {//2. 正在匹配中的状态下点击按钮,发送停止对战匹配请求var req_json = {optype: "match_stop"}ws_hdl.send(JSON.stringify(req_json));}}function get_user_info() {$.ajax({url: "/info",type: "get",success: function(res) {var info_html = "<p>" + "用户:" + res.username + " 积分:" + res.score + "</br>" + "比赛场次:" + res.total_count + " 获胜场次:" + res.win_count + "</p>";var screen_div = document.getElementById("screen");screen_div.innerHTML = info_html;ws_hdl = new WebSocket(ws_url);ws_hdl.onopen = ws_onopen;ws_hdl.onclose = ws_onclose;ws_hdl.onerror = ws_onerror;ws_hdl.onmessage = ws_onmessage;},error: function(xhr) {alert(JSON.stringify(xhr));location.replace("/login.html");}})}function ws_onopen() {console.log("websocket onopen");}function ws_onclose() {console.log("websocket onclose");}function ws_onerror() {console.log("websocket onerror");}function ws_onmessage(evt) {var rsp_json = JSON.parse(evt.data);if (rsp_json.result == false) {alert(evt.data);location.replace("/login.html");return;}if (rsp_json["optype"] == "hall_ready") {alert("游戏大厅连接建立成功!");}else if (rsp_json["optype"] == "match_success") {//对战匹配成功alert("对战匹配成功,进入游戏房间!");location.replace("/game_room.html");}else if (rsp_json["optype"] == "match_start") {console.log("玩家已经加入匹配队列");button_flag = "start";be.innerHTML = "匹配中....点击按钮停止匹配!";return;}else if (rsp_json["optype"] == "match_stop"){console.log("玩家已经移除匹配队列");button_flag = "stop";be.innerHTML = "开始匹配";return;}else {alert(evt.data);location.replace("/login.html");return;}}get_user_info();</script>
</body>
</html>
void ws_resp(wsserver_t::connection_ptr conn,Json::Value& resp){std::string body;json_util::serialize(resp,body);conn->send(body);} void wsmsg_game_hall(wsserver_t::connection_ptr conn,wsserver_t::message_ptr msg){Json::Value resp_json;std::string resp_body;//1.获取身份session_ptr ssp = get_session_by_cookie(conn);if(ssp.get() == nullptr){return;}std::string req_body = msg->get_payload();Json::Value req_json;bool ret = json_util::unserialize(req_body,req_json);if(ret == false){resp_json["result"] = false;resp_json["reason"] = "请求信息解析失败";return ws_resp(conn,resp_json);}//2.对于请求进行处理if(!req_json["optype"].isNull() &&req_json["optype"].asString() == "match_start"){//1.开始对战匹配 : 通过匹配模块,将用户添加到匹配队列中_mm.add(ssp->get_user());resp_json["optype"] = "match_start";resp_json["result"] = true;return ws_resp(conn,resp_json);}else if(!req_json["optype"].isNull() &&req_json["optype"].asString() == "match_stop"){//2.停止对战匹配 : 通过匹配模块,将用户从匹配队列中移除_mm.del(ssp->get_user());resp_json["optype"] = "match_stop";resp_json["result"] = true;return ws_resp(conn,resp_json);}//3.给客户端响应resp_json["optype"] = "unkonw";resp_json["result"] = false;return ws_resp(conn,resp_json);}void wsmsg_game_room(wsserver_t::connection_ptr conn,wsserver_t::message_ptr msg){//}void wsmsg_callback(websocketpp::connection_hdl hdl,wsserver_t::message_ptr msg){wsserver_t::connection_ptr conn = _wssrv.get_con_from_hdl(hdl);websocketpp::http::parser::request req = conn->get_request();std::string uri = req.get_uri();if(uri == "/hall"){return wsmsg_game_hall(conn,msg);}else if(uri == "/room"){return wsmsg_game_room(conn,msg);}}

五.目前效果演示(还没写房间内的游戏逻辑)

不要在同一个浏览器上进行登录两个用户session会有影响

两个全部匹配成功

目前房间内还没写,所以是这样的

http://www.dtcms.com/a/457232.html

相关文章:

  • Elastic 被评为 IDC MarketScape《2025 年全球扩展检测与响应软件供应商评估》中的领导者
  • 如何利用Python呼叫nexxim.exe执行电路模拟
  • APM学习(3):ArduPilot飞行模式
  • h5制作开发价目表常用seo站长工具
  • 忻州建设公司网站他达那非副作用太强了
  • pytest详细教程
  • 订单超时方案的选择
  • Redis 集群故障转移
  • 虚拟专用网络
  • 网站制作公司网站建设网站膳食管理东莞网站建设
  • Linux小课堂: 从零到上手的指南
  • DrissionPage防检测
  • 三亚官方网站建设ps如何做网页设计
  • Java体系总结——从基础语法到微服务
  • 深圳网站建设李天亮网站怎么做构成
  • Word卡顿,过很久才弹窗网络连接失败解决办法
  • 古典网站建设睢宁招标网官方
  • 告别物流乱象:商贸物流软件如何实现全流程可视化管理​
  • Ubuntu 20.04 安装mysql-5.7.9
  • 二、排版格式与注释
  • 计组2.2.1——加法器,算数逻辑单元ALU
  • 东莞网站建设公司注册郑州企业网站排名
  • 2025-10-08 Python 标准库 4——内置类型:数字类型
  • java ArrayList的add方法是插入到最后吗
  • Kotlin 判空写法对比与最佳实践
  • 如何在中国建设银行网站转账网站域名格式
  • OSI 七层模型
  • HTTP Client
  • 网络彩票网站建设电商具体是做什么的上班
  • 【C语言基础详细版】02. 数组详解:从概念到应用全面解析