上期我们完成了连接游戏数据交互的约定以及一些实体类的创建,这期我们继续完成websockt连接的的代码:
1. 建立连接交互
我们在afterConnectionEstablished()方法中给两个用户分别发送对战的初始信息:
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
GameReadyResponse response = new GameReadyResponse();
//1.获取用户信息
User user = (User)session.getAttributes().get("user");
if(user == null) {
System.out.println("用户未登录");
response.setMessage("no_login");
response.setOk(true);
response.setErrMsg("用户未登录");
session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
return;
}
//2. 检测用户是否进入房间
Room room = roomManager.getRoomByUserId(user.getUserId());
if(room == null) {
response.setOk(false);
response.setErrMsg("用户未成功进入房间");
System.out.println("用户未成功进入房间");
session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
return;
}
//3. 判断玩家是否在别处登录
if(onlineUserManager.getFromHall(user.getUserId()) != null
|| onlineUserManager.getFromRoom(user.getUserId()) != null) {
response.setMessage("repeat_login");
response.setOk(true);
response.setErrMsg("用户已在别处登录");
System.out.println("用户已在别处登录");
session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
return;
}
//4.设置玩家上线,维护游戏房间内在线状态
onlineUserManager.enterGameRoom(user.getUserId(), session);
synchronized (room) {
//5. 把玩家加入游戏房间
if(room.getUser1() == null) {
//对手还未进入房间
room.setUser1(user);
System.out.println("玩家 " + user.getUsername() + "进入游戏房间");
return ;
}
if(room.getUser2() == null) {
//对手已经进入房间
room.setUser2(user);
System.out.println("玩家 " + user.getUsername() + "进入游戏房间");
//随机设置先手玩家
if(System.currentTimeMillis() % 2 == 0) {
room.setBlackUser(room.getUser1().getUserId());
}else{
room.setBlackUser(room.getUser2().getUserId());
}
//通知玩家1
noticeGameReady(room, room.getUser1(), room.getUser2());
//通知玩家2
noticeGameReady(room, room.getUser2(), room.getUser1());
}
}
}
private void noticeGameReady(Room room, User user1, User user2) throws IOException {
GameReadyResponse response = new GameReadyResponse();
response.setMessage("gameReady");
response.setOk(true);
response.setRoomId(room.getRoomId());
response.setUserId1(user1.getUserId());
response.setUserId2(user2.getUserId());
response.setBlack(user1.getUserId() == room.getBlackUser());
onlineUserManager.getFromRoom(user1.getUserId())
.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
}
2. 断开连接处理
@Override
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
try {
User user = (User)session.getAttributes().get("user");
WebSocketSession exitSession = onlineUserManager.getFromRoom(user.getUserId());
if(exitSession.equals(session)) {
onlineUserManager.exitGameRoom(user.getUserId());
System.out.println("连接异常断开," + user.getUsername() + "退出游戏房间");
}
}catch (NullPointerException e) {
//出现空指针异常说明用户未登录
e.printStackTrace();
}
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
try {
User user = (User)session.getAttributes().get("user");
WebSocketSession exitSession = onlineUserManager.getFromRoom(user.getUserId());
if(exitSession.equals(session)) {
onlineUserManager.exitGameRoom(user.getUserId());
System.out.println("连接正常断开," + user.getUsername() + "退出游戏房间");
}
}catch (NullPointerException e) {
//出现空指针异常说明用户未登录
e.printStackTrace();
}
}