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

wordpress备份 方案百度seo排名优化公司哪家强

wordpress备份 方案,百度seo排名优化公司哪家强,怎么调查建设网站,offic做网站的软件文章目录 处理连接成功通知玩家就绪逻辑图问题 1:线程安全问题 2:先手判定错误两边都是提示:轮到对方落子![image.png](https://i-blog.csdnimg.cn/img_convert/c570cd26eadbe87ed467bc4edaa7945e.png) 处理连接成功 实现 GameAPI 的 afterC…

文章目录

  • 处理连接成功
  • 通知玩家就绪
  • 逻辑图
  • 问题 1:线程安全
  • 问题 2:先手判定错误
    • 两边都是提示:轮到对方落子![image.png](https://i-blog.csdnimg.cn/img_convert/c570cd26eadbe87ed467bc4edaa7945e.png)

处理连接成功

实现 GameAPIafterConnectionEstablished 方法

  • 首先需要检测用户的登录状态(从 session 中拿到当前用户信息)
  • 然后要判定当前玩家是否是在房间中
  • 接下来进行多开判定,如果玩家已经在游戏中,则不能再次连接
  • 把两个玩家放到对应的房间对象中,当两个玩家都建立了连接,房间就放满了,这个时候通知双方都准备就绪
  • 如果有第三个玩家尝试也想加入房间,则给出一个提示,房间已经满了
@Override  
public void afterConnectionEstablished(WebSocketSession session) throws Exception {  GameReadyResponse resp = new GameReadyResponse();  // 1. 先获取到用户的身份信息(从 HttpSession 里面拿到当前用户的对象)  User user = (User) session.getAttributes().get("user");  if(user == null) {  resp.setOk(false);  resp.setReason("用户尚未登录!");  session.sendMessage(new TextMessage(objectMapper.writeValueAsString(resp)));  return;  }  // 2. 判定当前用户是否已经在房间里(拿房间管理器 RoomManager 进行查询)  Room room = roomManager.getRoomByUserId(user.getUserId());  if (room == null) {  // 如果为 null,当前没有找到对应的房间,就是该玩家还没有匹配到  resp.setOk(false);  resp.setReason("用户尚未匹配到!");  session.sendMessage(new TextMessage(objectMapper.writeValueAsString(resp)));  return;  }  // 3. 判定当前是不是多开(该用户是不是已经在其他地方进入游戏了)  //    前面准备了一个 OnlineUserManager    if (onlineUserManager.getFromGameRoom(user.getUserId()) != null  || onlineUserManager.getFromGameHall(user.getUserId()) != null) {  // 如果一个账号,一边是在游戏大厅,一边是在游戏房间,也视为多开  resp.setOk(false);  resp.setReason("禁止多开游戏页面!");  session.sendMessage(new TextMessage(objectMapper.writeValueAsString(resp)));  }  // 4. 设置当前玩家上线  onlineUserManager.enterGameHall(user.getUserId(), session);  // 5. 把两个玩家加入到游戏房间中  //    当前这个逻辑是在 game_room.html 页面加载的时候进行的,  //    前面的创建房间/匹配过程,是在 game_hall.html 页面中完成的  //    因此前面匹配到对手之后,需要经过页面跳转,来到 game_room.html 才算正式进入游戏房间(玩家准备就绪)  //    直行到当前逻辑,说明玩家已经页面跳转成功了  //    页面跳转是很有可能出现失败的情况的(成本高,风险大)  if (room.getUser1() == null) {  // 第一个玩家还未加入房间,就把当前连上 websocket 的玩家作为 user1 加入到房间中  room.setUser1(user);  // 把先连入房间的玩家作为先手  room.setWhiteUser(user.getUserId());  System.out.println("玩家 " + user.getUsername() + " 作为玩家1,已经准备就绪!");  return;}  if (room.getUser2() == null) {  // 如果进入这个逻辑,说明玩家1 已经加入房间,现在要给当前玩家作为玩家2  room.setUser2(user);  System.out.println("玩家 " + user.getUsername() + " 作为玩家2,已经准备就绪!");  // 当两个玩家都加入成功之后,就要让服务器,给这两个玩家都返回 websocket 的响应数据  // 通知这两个玩家:游戏双方都已经准备好了  // 通知玩家1  noticeGameReady(room, room.getUser1(), room.getUser2());  // 通知玩家2  noticeGameReady(room, room.getUser2(), room.getUser1());  return;  }  // 6. 此处又有玩家尝试连接同一个房间,就提示报错  //    这种情况理论上是不存在的,为了让程序更加的健壮,还是做一个判定和提示  resp.setOk(false);  resp.setReason("当前房间已满,你不能加入房间!");  session.sendMessage(new TextMessage(objectMapper.writeValueAsString(resp)));
}  private void noticeGameReady(Room room, User thisUser, User thatUser) throws IOException {  GameReadyResponse resp = new GameReadyResponse();  resp.setMessage("gameReady");  resp.setOk(true);  resp.setReason("");  resp.setRoomId(room.getRoomId());  resp.setThisUserId(thisUser.getUserId());  resp.setThatUserId(thatUser.getUserId());  resp.setWhiteUser(room.getWhiteUser());  // 把当前的响应数据传回给玩家  WebSocketSession session = onlineUserManager.getFromGameRoom(thisUser.getUserId());  session.sendMessage(new TextMessage(objectMapper.writeValueAsString(resp)));
}

image.png

  • 之前已经写了一个 OnlineUserManager 对象了,也确实能够管理一些用户的在线状态
  • 但是这个状态仅仅是局限在 game_hall 这个页面中
  • 现在我们已经是在 game_room 中了

image.png

  • 之前在退出 game_hall 页面的时候,就会断开 websocket 连接,也就会在服务器的 OnlineUserManager 中删掉对应的元素

因此玩家从游戏大厅离开之后,进入游戏房间页面的时候,就需要重新管理用户的在线状态了

通知玩家就绪

@Override  
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {  User user = (User) session.getAttributes().get("user");  if (user == null) {  // 此处我们简单处理,在断开连接的时候就不给客户端返回响应了  return;  }  WebSocketSession existSession = onlineUserManager.getFromGameRoom(user.getUserId());  if(session == existSession) {  // 加上这个判定,目的是为了避免在多开的情况下,第二个用户退出连接动作,导致第一个用户的会话被删除  onlineUserManager.exitGameRoom(user.getUserId());  }  System.out.println("当前用户 " + user.getUsername() + " 游戏房间连接异常!");  
}

逻辑图

对战模块-连接房间.png

问题 1:线程安全

在玩家 1 连入服务器和玩家 2 连入服务器这两个操作,就是并发的

  • 不能保证是上面逻辑图中 1 先建立,2 后建立的顺序
  • 这就意味着代码中的这段逻辑是存在多线程环境下调用的,可能会出现线程安全问题 image.png
  • 我们就要把这里的逻辑判定,使用锁保护起来,避免多个客户端都认为自己是先手方

需要竞争的资源是什么,就对什么加锁

  • 对谁加锁,针对这个对象访问的时候才有互斥效果
  • 此时我们是多个线程在同时访问、修改同一个 room 对象
  • 所以我们需要针对 room 对象加锁

image.png|529

  • 要保证玩家 1 和 2 要互斥,玩家 3 和 4 要互斥,玩家 5 和 6 要互斥
  • 同个房间里的两个对象才会有竞争,非同房里面的玩家互不干扰image.png|471

问题 2:先手判定错误

两边都是提示:轮到对方落子image.png

image.png|366

  • 客户端代码中尝试获取响应中的 isWhite 字段
  • 但是实际响应的数据中,根本就灭有 isWhite 字段,有的是 whiteUser 字段image.png
  • 因此代码中进行取这个字段,就都取到了一个 undefined,这里的判断结果都为 false,所以在先手选择都是选择对方image.png

解决办法:image.png
image.png

http://www.dtcms.com/wzjs/519034.html

相关文章:

  • 代理 指定网站 hostseo研究中心vip教程
  • 河北邢台人品怎么样宁波免费seo排名优化
  • 江苏兴力建设集团有限公司网站自助建站系统源码
  • wordpress微博插件外贸seo网站建设
  • 影院网站怎么做app开发费用一般多少钱
  • php网页制作实例怎么优化网络
  • 教育中介公司网站建设费用seo优化 搜 盈seo公司
  • premium WordPressseo静态页源码
  • 金华建设网站公司百度网站收录
  • 一分钟建站网络营销的发展现状如何
  • 靖江网站定制宁波网站建设与维护
  • 英文网站建设深圳兔子bt搜索
  • 软件开发工具与环境自考真题07169网站seo培训
  • 自己建站市场调研方法有哪些
  • 岫岩网站建设电商运营怎么做如何从零开始
  • 付费阅读网站代码网易搜索引擎入口
  • 防腐木做水车网站数据分析平台
  • 网站建设带支付源码西安网站排名优化培训
  • 哪里可以做网站开发个人优秀网页设计
  • 天猫分销平台推广网站排名优化seo教程
  • 电子商务网站业务流程电脑培训班在哪里有最近的
  • 如何用wix做网站百度快照是什么意思
  • 重庆装修网站建设上海seo优化
  • 1920的做网站做多大百度联盟是什么
  • 网站制作在哪里找appstore关键词优化
  • 网页markdown转wordpressaso优化教程
  • 郑州网站建设国奥大厦软文推广公司
  • 网站运营与公司今日新闻内容摘抄
  • 南平企业网站建设51链
  • 叙述网站制作的流程建站之星网站