더북(TheBook)

▼ templates/messages.tmpl

<div class="page-header">
    <h4>메시지
        <small id="room-name"></small>
    </h4>
</div>
  
<div class="panel panel-default">
    <div id="messages" class="panel-body">
    </div>
    <div class="panel-footer">
        <div class="media">
            <div class="media-body">
                <form id="chatbox">
                    <input type="text" class="form-control" id="message" placeholder="메시지를 입력하세요">
                </form>
            </div>
        </div>
    </div>
</div>
<script type="text/javascript">
    var socket = null;
  
    function enterRoom(roomId) {
        // 채팅방에 입장하면 "GET /rooms/:id/messages"를 호출해 메시지를 조회하고 화면에 보여줌
        $.get("/rooms/" + roomId + "/messages", function(data) {
            $("#messages").empty();
            if (data != null) {
                for (var i = data.length - 1; i >= 0; i--) {
                    addMessage(data[i]);
                };
            }
        })
  
        // 연결된 소켓을 종료하고 입장한 채팅방 아이디로 새로운 소켓 생성
        if (socket != null) {
            socket.close();
        }
        socket = new WebSocket(socketEndPoint + roomId);
        socket.onmessage = function(e) {
            addMessage(JSON.parse(e.data));
        }
  
    }
  
    // 화면에 message를 보여줌
    function addMessage(message) {
        var img = $("<div>").addClass("media-left").append(
            $("<img>").addClass("img-thumb").css({
                width: 30
            }).attr("src", message.user.avatar_url)
        );
        var msg = $("<div>").addClass("media-body").append(
            $("<h6>").text(message.user.name + " ").addClass("media-heading")
            .append($("<small>").text(new Date(message.created_at).toLocaleString())),
            $("<p>").text(message.content));
  
        $("#messages").append($("<div>").addClass("media").append(img, msg));
    }
  
    // 소켓 연결이 완료되지 않으면 소켓 연결이 완료될 때까지 대기 후 callback 실행
    function waitForSocketConnection(socket, callback) {
        setTimeout(
            function() {
                if (socket.readyState === 1) {
                    if (callback != null) {
                        callback();
                    }
                    return;
                } else {
                    console.log("wait for connection...")
                    waitForSocketConnection(socket, callback);
                }
  
           }, 5); // 소켓 연결이 완료될 때까지 5밀리초 단위로 소켓 연결 상태 확인
    }
  
    $(function() {
        var msgBox = $("#chatbox input#message");
        // "chatbox"를 submit하면 소켓을 통해 "chatbox"에 입력한 메시지 전송
        $("#chatbox").submit(function() {
            if (!msgBox.val()) return false;
            if (!socket) {
                console.log("Error: There is no socket connection.");
                return false;
            }
            waitForSocketConnection(socket, function() {
                socket.send(JSON.stringify({
                    "room_id": currentRoomId,
                    "content": msgBox.val()
                }));
                msgBox.val("");
            })
            return false;
        });
    });
</script>

enterRoom() 함수가 호출되면 enterRoom() 함수에 전달된 채팅방 아이디(roomId)로 해당 채팅방에 있는 메시지를 조회한다. 그리고 조회한 메시지를 addMessage() 함수로 화면에 출력한다.

신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.