노출되는 이미지가 불편하시겠지만 양해를 구합니다. 노출, 클릭등에 관한 자료로 활용 중입니다.

-- 미완성... 작성중...입니다.


실시간 댓글(발언/논평) 시스템 만들기




Why Should We Care About The Real-Time Web?

비록 실시간웹은 상대적으로 최근에 메인스트림 구절이지만, 실시간 웹 기술은 10여년이 넘게 되어 간다.


SOCIAL MEDIA DATA

소셜 미디어가,그리고 특히 트위터는, 갖는 의미는 더욱 더 데이타는 즉시 가용해져야 한다.


INCREASED USER EXPECTATIONS

더 많은 사용자가 트위터와 페이스북과 같은 어플을 사용하는 것으로 이동하게 되어, 그것들이 전달되는 사용자의 경험, 웹어플의 기대되어 지는 것들의 인지등이 변했다.


WEBSOCKETS

이전에 내가 언급했듯이 이전 솔루션은 서버에게 즉시 데이타를 웹브라우저로 푸시하는 것은 해킹으로 여겨졌다. 그러나 없어지지 않는 사실은 표준화되는 방법과 크로스 브라우저를 하는 능력이 요구되었다.

우리의 플레이어들은 마침내 HTML5 웹소켓을 가지고 해결을 해왔다.


HOW ARE REAL-TIME TECHNOLOGIES BEING USED?

실시간 웹 테크놀러지는 사용자 경험를 개선하는 것을 이끌고, 모든 종류의 매력적인 기능을 만드는 것을 가능하게 해 준다.


여기(아래는) 보통 사용되는 사용사례의 모음이다.

* Realtime Stats - 이 기술은 처음에 금융에서 주식 교환 정보를 보여주기 위해 쓰였고,

* Notifications - 어떤것을 사용자가 가용해지거나 변화에 관심을 가질때

* Activity Streams - 친구나 제품의 활동의 흐름

* Chat - 실시간 웹 기술 그러나 여전히 매우 값어치 있는 함수.

* Collaboration - 구글docs는 그들 문서안에서 이런 기능들의 종류를  제공한다.

* Multiplayer Games - 사용자의 움직임을 실시간으로 전달하는 능력, 게임 상태의 변화 그리고 점수의 갱신은 멀티플레이어 게임에서 매우 명확하게 중요하다.



Creating Generic Blog Commenting System


START FROM A TEMPLATE

나는 블로그 post에 실시간 댓글을 추가하는 것을 집중하려 하고, template으로 부터 시작을 하자.

이 template은 Coding An HTML 5 Layout From Scratch의 포스트에서 정의된 HTML 5 layout을 재사용한다.

 

 


/css(dir)

global-forms.css

main.css

reset.css

/images(dir)

/index.php


GitHub(https://github.com/pusher-community/realtime-commenting/tree/start)


HTML

주요소는

-<section id="content"> : 블로그 post content

-<section id="comments"> : comments가 보여지는 위치. 이것이 이 작업으로 만들어 지는 주요 위치이다.


COMMENTS ( 댓글 쓰는 Form추가 )

<div id="respond">가 <section id="comments">로 둘러 쌓인 채 추가 된다.

Leave a Comment

<-- comment_post_ID value hard-coded as 1 -->

COMMENT FORM CSS ( 댓글 쓰기 css 설정 )

#respond, #respond input, #respond textarea를 설정

#respond {
  margin-top: 40px;
}

#respond input[type='text'],
#respond input[type='email'], 
#respond textarea {
  margin-bottom: 10px;
  display: block;
  width: 100%;

  border: 1px solid rgba(0, 0, 0, 0.1);
  -webkit-border-radius: 5px;
  -moz-border-radius: 5px;
  -o-border-radius: 5px;
  -ms-border-radius: 5px;
  -khtml-border-radius: 5px;
  border-radius: 5px;

  line-height: 1.4em;
}


HANDLING COMMENT SUBMISSION ( POST 수신 부분 작성 )

form에서 전송하는 것을 받아들이고 저장하는 post_comment.php를 작성


add_comment($_POST) ) {
  header( 'Location: index.php' );
}
else {
  header( 'Location: index.php?error=Your comment was not posted due to errors in your form submission' );
}
?>


여기서는 실시간 기능에 관해서만 다루니 Persistence.php로 정의된 Template class를 사용

접속자의 $_SESSION을 사용해서 저장하는 방식으로 필요하다면 재수정을 해서 사용


DISPLAYING THE COMMENTS WITH THE BLOG POST

마지막으로 일반적인 블로그 코멘트 시스템을 설정해야 하는 것은 블로그 페이지를 갱신하는것이고, Persistence 객체로 부터 코멘트를 가져와서 보여주는 것이다.

$comment_post_ID는 1로 임의설정

아래 부분은 index.php상단에 위치(Redirect/Loading시에 가져옴)

get_comments($comment_post_ID);
$has_comments = (count($comments) > 0);
?>


POST시에도 해당 값으로 전달



모든 댓글을 보여주는 영역도 index.php에 설정

  1. Be the first to add a comment.
  2. By


Prograssive Enhancement With jQuery

블로그 댓글 시스템을 웹페이지 처럼 느끼지 않고, 어플처럼 느끼도록하는 과정의 첫 단계는

사용자가 댓글을 등록하면, 페이지가 reload되는 것을 중지 시키는 것이다.

이것은 댓글을 서버로 전송(등록)시 AJAX 요청을 사용할 수 있다.

여기서 사용할  jQuery는 크로스브라우저 자바스크립터 기능으로 표준이다.

만들 자바스립터를 위해 새로운 폴더를 만들고, 거기에 어플리케이션 스크립터를 위한 파일을 위치 시킨다.




CAPTURE THE COMMENT FORM SUBMISSION

form의 submit 이벤트를 웹페이지는 bind준비한다.

$(function() {
  $('#commentform').submit(handleSubmit);
});

form이 전송되게되면, handleSumbit함수는 form에서 추출한 서버로 보내길 원하는 댓글data를 모은다.

function handleSubmit() {
  var form = $(this);
  var data = {
    "comment_author": form.find('#comment_author').val(),
    "email": form.find('#email').val(),
    "comment": form.find('#comment').val(),
    "comment_post_ID": form.find('#comment_post_ID').val()
  };

  postComment(data);

  return false;
}

function postComment(data) {
  // send the data to the server
}


POST THE COMMENT WITH AJAX

postComment함수안에서 서버로 POST요청하여 form으로 부터 조회한 data를 전달한다.

또한 2개의 처리자:postSucces와 postError를 정의할 수 있다

function postComment(data) {
  $.ajax({
    type: 'POST',
    url: 'post_comment.php',
    data: data,
    headers: {
      'X-Requested-With': 'XMLHttpRequest'
    },
    success: postSuccess,
    error: postError
  });
}

function postSuccess(data, textStatus, jqXHR) {
  // add comment to UI
}

function postError(jqXHR, textStatus, errorThrown) {
  // display error
}


DYNAMICALLY UPDATING THE USER INTERFACE WITH THE COMMENT

서버에 댓글이 전달되고 저장되는 시점이지만 AJAX response는 어떤 의미 있는 응답을 제공하지 않는다.

또한, 사용자가 페이지를 갱신해서 보려고 해도, 댓글 영역은 새로 등록된 댓글을 보여주기 위해 갱신되지 않는다

이제, UI를 갱신하고 기능적으로 테스트하는 code를 작성한다.

function postSuccess(data, textStatus, jqXHR) {
  $('#commentform').get(0).reset();
  displayComment(data);
}
  
function displayComment(data) {
  var commentHtml = createComment(data);
  var commentEl = $(commentHtml);
  commentEl.hide();
  var postsList = $('#posts-list');
  postsList.addClass('has-comments');
  postsList.prepend(commentEl);
  commentEl.slideDown();
}

function createComment(data) {
  var html = '' +
  '
  • ' + '' + '
    ' + '

    ' + data.comment + '

    ' + '
    ' + '
  • '; return html; } function parseDisplayDate(date) { date = (date instanceof Date? date : new Date( Date.parse(date) ) ); var display = date.getDate() + ' ' + ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'][date.getMonth()] + ' ' + date.getFullYear(); return display; }


    DETECT AND RESPONDING TO THE AJAX REQUEST

    post_comment.php갱신하여 AJAX call을 감지하고, 새로 생성된 댓글에 관한 정보를 return한다.

    // if (  isset($_SERVER['HTTP_X_REQUESTED_WITH']) ) {} 
    $ajax = ($_SERVER[ 'HTTP_X_REQUESTED_WITH' ] === 'XMLHttpRequest');
    


    add_comment($_POST);
    
    if($ajax) {
      sendAjaxResponse($added);
    }
    else {
      sendStandardResponse($added); 
    }
    
    function sendAjaxResponse($added) {
      header("Content-Type: application/x-javascript");
      if($added) {
        header( 'Status: 201' );
        echo( json_encode($added) );
      }
      else {
        header( 'Status: 400' );
      }
    }
    
    function sendStandardResponse($added) {
      if($added) {
        header( 'Location: index.php' );
      }
      else {
        header( 'Location: index.php?error=Your comment was not posted due to errors in your form submission' );
      }
    }
    ?>
    


    Getting Real-Time - Finally !

    여기까지, ..위에서 작업한 것들이 가치가 있는 것이다. Pusher를 추가하는 것은 아주 쉽다.

    WHAT IS PUSHER?

    Pusher는 호스팅되는 서비스로 빠르고 쉽게 실시간 기능을 웹이나 모바일 앱에 추가하도록 해 준다.

    이것은 RESTful API를 제공해서 쉽게 어떤 앱에서 오는 이벤트도 쉽게 publish한다.

    이는 HTTP request와 WebSocket API이 실시간 양방향 통신을 위해 사용된다.

    SIGN UP FOR PUSHER AND GET YOUR API CREDENTIALS

    가입하고 API인증 값을 얻기, pusher_config.php에

    
    

    index.php에서 require를 추가를 한다. JavaScript에서 APP_KEY를 사용할 수 있도록 만들고,Pusher로 연결시에 사용

    
    
    
    

    REAL-TIME JAVASCRIPT

    첫번째 할일은 Pusher를 앱에 추가할때 Pusher 자바스크립트library를 포함시키고 Pusher로 연결한다.

    
    
    
    

    app.js에 Pusher기능을 추가한다.

    var pusher = new Pusher(APP_KEY);
    var channel = pusher.subscribe('comments-' + $('#comment_post_ID').val());
    channel.bind('new_comment', displayComment);
    


    SENDING REAL-TIME EVENTS USING THE EVENT CREATOR

    Event Creator를 사용해서 서버측code를 작성하지 않고 기능을 테스트할 수 있다.

    위의 코드에서 event명은 'new_comment'이고 'comments-1'채널이다

    REAL-TIME PHP

    -index.php
    -css (dir)
    -images (dir)
    -post_comment.php
    -pusher_config.php
    -Persistence.php
    -squeeks-Pusher-PHP (dir)
    --lib (dir)
    ---Pusher.php
    

    이벤트는 아래 몇줄로 작동이 가능해진다.

    trigger('comments-1', 'new_comment', array(
      "comment_post_ID" => 1,
      "date" => "Tue, 21 Feb 2012 18:33:03 +0000",
      "comment" => "The realtime Web rocks!",
      "comment_author" => "Phil Leggetter"
    ));
    ?>
    

    몇가지 logic를 추가해야한다. trigger이벤트 전에

    - comment가 추가된것을 확인하고

    - $added 배열에서 unique댓글 구분자를 추출하고

    - 채널명을 구문하는 문자를 만든다

    - new_comment이벤트를 채널명에 $added 데이타를 보내도록 한다.

    post_comment.php

    add_comment($_POST);
    
    if($added) {
      $channel_name = 'comments-' . $added['comment_post_ID'];
      $event_name = 'new_comment';
    
      $pusher = new Pusher(APP_KEY, APP_SECRET, APP_ID);
      $pusher->trigger($channel_name, $event_name, $added);
    }
    
    if($ajax) {
      sendAjaxResponse($added);
    }
    else {
      sendStandardResponse($added); 
    }
    
    function sendAjaxResponse($added) {
      header("Content-Type: application/json");
      if($added) {
        header( 'Status: 201' );
        echo( json_encode($added) );
      }
      else {
        header( 'Status: 400' );
      }
    }
    
    function sendStandardResponse($added) {
      if($added) {
        header( 'Location: index.php' );
      }
      else {
        header( 'Location: index.php?error=Your comment was not posted due to errors in your form submission' );
      }
    }
    ?>
    

    2개의 다른 browser 창에서 앱을 실행하면,하나의 창에서 댓글을 추가하자마자, 2번째 창에서 댓글이 (매직처럼)바로 나타나다.

    이제 실시간 댓글 시스템을 갖는거다.


    demo running : http://realtime-commenting.herokuapp.com/

    ( 소스 : https://github.com/pusher-community/realtime-commenting )


    Good Real-Time App Development Practices


    USE BROWSER DEVELOPER TOOLS


    CHECK CONNECTIVITY



    Conclusion



    원문 : How To Build A Real-Time Commenting System

    https://www.smashingmagazine.com/2012/05/building-real-time-commenting-system/





    블로그 이미지

    StartGuide

    I want to share the basic to programming of each category and how to solve the error. This basic instruction can be extended further. And I have been worked in southeast Asia more than 3 years. And I want to have the chance to work another country.

    ,