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

代搭建网站网络营销的方法

代搭建网站,网络营销的方法,做seo的网站是怎么样的,使用wordpress搭建网站文章目录 处理连接成功通知玩家就绪逻辑图问题 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/442312.html

相关文章:

  • 个人中心页面设计图片浙江企业seo推广
  • 自建服务器做网站网络宣传平台有哪些
  • 临沂企业建站系统模板企业网站建设服务
  • 网站做采集会有问题么企业管理软件管理系统
  • 社区做图网站营销案例100例
  • 做pc端网站适配苏州百度
  • 网站建设开发协议新网域名注册
  • 一个做BAT笔试题的网站重庆森林百度云
  • 嘉兴建企业网站seo视频教程我要自学网
  • 做网站生意买螃蟹淘宝推广怎么推
  • wordpress如何缩短URL黄山seo排名优化技术
  • 承德哪里做网站微博推广方式有哪些
  • wordpress主题php详解seo案例分析及解析
  • 简洁的网站建设合同北京建站公司
  • 比较好的免费外贸网站搜索引擎登录入口
  • 有点子外包做网站会不会被盗窃西安seo主管
  • wordpress主题有后台武汉seo关键词排名
  • 邢台做移动网站费用如何快速提升网站关键词排名
  • wordpress怎么实现会员登录西安网络seo公司
  • 网站建设流量是怎么回事注册网站需要多少钱
  • 工会网站升级改造建设方案成都品牌推广
  • 卧龙区建网站在线代理浏览网页
  • 外贸网站建设公司青岛网站优化排名易下拉排名
  • 宁阳房产网优化推广关键词
  • 汕头网站关键词排名南宁百度关键词排名公司
  • 山东网站建设哪家好关键词排名是由什么决定的
  • 网站链接如何做日历提醒系统优化app
  • .net网站开发课程设计手机优化器
  • 做网站具体收费抖音seo软件
  • 怎么用ps做网站图片怎样建立一个网络销售平台