iT邦幫忙

2022 iThome 鐵人賽

DAY 24
0

今日目標,「退出房間」和「踢出房間」的功能。

其實「退出房間」跟「踢出房間」是同個方法,指定 username 將其踢出去即可,而退出房間小弟也是用 API 的調用來實現。

  1. 先修改一下之前的一些東西
    • Room 的 owner 增加 @Setter 註解
    • RoomList 新增方法 destroy() 用於銷毀房間,加入的片段程式碼為:
      public void destroy(String roomId) {
          this.roomList.remove(roomId);
      }
      
  2. 在 RoomService 提供服務 quitRoom,加入的片段程式碼為:
    public boolean quitRoom(String user, String roomId) {
        // 根本沒有這個 user
        if (!this.userStatus.containsUser(user)) {
            return false;
        }
    
        // user 根本不在房間
        if (!this.userStatus.isUserInRoom(user)) {
            return false;
        }
    
        // 這個房號不存在
        if (!this.roomList.containRoomId(roomId)) {
            return false;
        }
    
        Room room = roomList.getRoomById(roomId);
    
        // 如果退出的是房主,要另外處理
        if (room.getOwner().equals(user)) {
            // 如果房間人數等於 1,表示整個房間只有房主,那就需要把這個房間銷毀
            // 否則,從其他成員選擇一人擔任新房主
            if (room.count() == 1) {
                this.roomList.destroy(roomId);
            }
            else {
                String newOwner = room.getAllMembers().get(1);
                room.setOwner(newOwner);
                room.removeGuest(newOwner);
                this.userStatus.setUserReady(newOwner, false);
            }
        }
        else {
            room.removeGuest(user);
        }
    
        this.userStatus.setUserInRoom(user, false);
        this.userStatus.setUserRoomId(user, "");
    
        Map<String, Object> response = new HashMap<>();
        response.put("roomInfo", room.getInfo());
    
        simpMessagingTemplate.convertAndSendToUser(user, "/queue/room-info", response);
        return true;
    }
    
  3. 定義資料格式,在 room package 底下新增一個 java class,名稱為 UserQuitRoomMessage,內容為:
    package com.example.room;
    
    import lombok.Getter;
    import lombok.Setter;
    
    @Getter @Setter
    public class UserQuitRoomMessage {
        private String username;
        private String roomId;
    }
    
  4. 修改 RoomController,新增 quitRoomProcess() 的方法,加入的片段程式碼為:
    @PostMapping("/room/quit")
    @ResponseBody
    public ResponseEntity<Map<String, Object>> quitRoomProcess(UserQuitRoomMessage userQuitRoomMessage) {
        Map<String, Object> response = new HashMap<>();
        HttpStatus httpStatus;
        String message;
    
        if (!userService.isLogin()) {
            httpStatus = HttpStatus.FORBIDDEN;
            message = "未登入";
            response.put("message", message);
            return ResponseEntity.status(httpStatus).body(response);
        }
    
        String username = userQuitRoomMessage.getUsername();
        String roomId = userQuitRoomMessage.getRoomId();
        String me = userService.getUsername();
    
        // 避免有人利用 API 在非房主的情況下把其他人踢掉
        if (!username.equals(me) && !roomList.getRoomById(roomId).getOwner().equals(me)) {
            httpStatus = HttpStatus.FORBIDDEN;
            message = "權限不足";
            response.put("message", message);
            return ResponseEntity.status(httpStatus).body(response);
        }
    
        // 將使用者移除
        if (roomService.quitRoom(username, roomId)) {
            httpStatus = HttpStatus.OK;
            message = "成功";
            roomService.sendRoomInfo(roomId);
        }
        else {
            httpStatus = HttpStatus.BAD_REQUEST;
            message = "Error";
        }
        response.put("message", message);
        return ResponseEntity.status(httpStatus).body(response);
    }
    
  5. 修改 room.js,新增 quitRoom() 的方法,加入的片段程式碼為:
    // 綁定退出圖案的按鈕
    $("#quit-room-button").click(() => {
        quitRoom(myUsername);
    })
    
    function quitRoom(username) {
        let data = {
            username : username,
            roomId : roomId,
        };
        jq.post(
            "/room/quit",
            data,
            (response) => {
                console.log(response);
            }
        )
        .fail(function(e) {
            console.log(e);
        })
    }
    
  6. It's demo time
    • 創建房間,再退出
    • 創建房間,另一個加入再退出
    • 另一個加入後,房主將其踢出
    • 另一個加入後,房主退出

今天實作了退出和踢出的功能,也因為之前思考不周,所以又回去補了相關類別的操作 /images/emoticon/emoticon13.gif


上一篇
Day 22 - 準備
下一篇
Day 24 - 卡
系列文
Spring Boot... 深不可測31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言