가장 빨리 만나는 Go 언어 Unit 67.2 HTML과 JavaScript로 웹페이지 작성하기

저작권 안내
  • 책 또는 웹사이트의 내용을 복제하여 다른 곳에 게시하는 것을 금지합니다.
  • 책 또는 웹사이트의 내용을 발췌, 요약하여 강의 자료, 발표 자료, 블로그 포스팅 등으로 만드는 것을 금지합니다.

실전 예제: 채팅 서버 작성하기

이재홍 http://www.pyrasis.com 2014.12.17 ~ 2015.02.07

HTML과 JavaScript로 웹페이지 작성하기

이제 index.html 파일을 만들 차례입니다. 다음 내용을 GOPATH/src/chat/index.html 파일로 저장합니다.

GOPATH/src/chat/index.html
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <title>Go Chatting</title>

  <!-- CDN의 Bootstrap 사용 -->
  <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">

  <!-- CDN의 jQuery 사용 -->
  <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

  <!-- 웹 브라우저용 socket.io JavaScript 파일 -->
  <script src="//cdn.socket.io/socket.io-1.3.3.js"></script>

  <style>
    .container {
      margin-top:30px;
    }
    #messageList {
      width:600px;
      height:320px;
      padding: 10px 10px 10px 10px;
    }
    #inputBox {
      width:600px;
    }
  </style>
</head>

...

HTML의 <head> 태그에 사용할 CSS와 JavaScript 라이브러리를 지정합니다. 여기서는 CDN에 올라와있는 Bootstrap CSS와 jQuery, socket.io JavaScript 파일을 사용하겠습니다(CDN을 사용하지 않고 파일을 웹 서버에서 직접 전송해줘도 됩니다). 그리고 반드시 웹 브라우저용 socket.io JavaScript 파일을 사용해야 서버와 정상적으로 통신할 수 있습니다.

HTML로 대화 창과 메시지 입력 창을 구성합니다.

GOPATH/src/chat/index.html
...

<body>
  <div class="container">
    <div class="row">
      <div class="panel panel-primary" id="messageList"><!-- 대화 창 -->
      </div>
    </div>
    <div class="row">
      <div id="inputBox"><!-- 메시지 입력 창 -->
        <div class="input-group">  
          <input type="text" class="form-control" id="message" placeholder="Message">
          <span class="input-group-btn">
            <button class="btn btn-default" id="send" type="button">Send</button>
          </span>
        </div>
      </div>
    </div>
  </div>

...

여기서는 Bootstrap의 콤포넌트와 CSS를 사용했으며 Bootstrap 사용 방법은 따로 설명하지 않겠습니다.

이제 JavaScript로 socket.io 통신 부분과 채팅 메시지 처리 부분을 구현합니다.

GOPATH/src/chat/index.html
<body>

...

  <script>
    var socket = io(); // socket.io 객체 생성

    // 서버에서 이벤트가 왔을 때 실행할 콜백 함수 설정
    socket.on('event', function (data) {
      var msg
      switch (data.EvtType) { // 이벤트 타입을 판별하여 메시지 생성
      case 'message':
        msg = data.User + ': ' + data.Text;
        break;
      case 'join':
        msg = data.User + '님이 입장했습니다.';
        break;
      case 'leave':
        msg = data.User + '님이 퇴장했습니다.';
        break;
      }

      // <div> 태그를 생성하여 채팅 메시지를 넣어줌
      col = $('<div>').addClass('col-md-12').text(msg)
      row = $('<div>').addClass('row').append(col)
      list = $('#messageList').append(row)
      if (list.children().size() > 15)   // 채팅 메시지가 15개를 넘어가면
        list.find('div:first').remove(); // 메시지 삭제
    });

    // 채팅 메시지를 서버에 보내는 함수
    send = function () {
      msg = $('#message').val()      // 입력 상자에서 메시지를 가져옴
      if (msg != '') {               // 메시지가 있으면
        socket.emit('message', msg); // 서버에 메시지를 보냄
        $('#message').val('');       // 입력한 데이터 삭제
      }
    }

    // 보내기 버튼으로 메시지를 보냄
    $('#send').click(function () {
      send()
    });

    // 엔터 키 입력으로 메시지를 보냄
    $('#message').keyup(function(e) {
      if (e.keyCode == 13) { // 13이면 엔터 키
        send()
      }
    });
  </script>
</body>
</html>

먼저 io 함수로 socket.io 객체를 생성합니다.

var socket = io(); // socket.io 객체 생성

서버에서 event 메시지가 왔을 때 실행할 콜백 함수를 설정합니다.

// 서버에서 이벤트가 왔을 때 실행할 콜백 함수 설정
socket.on('event', function (data) {
  var msg
  switch (data.EvtType) { // 이벤트 타입을 판별하여 메시지 생성
  case 'message':
    msg = data.User + ': ' + data.Text;
    break;
  case 'join':
    msg = data.User + '님이 입장했습니다.';
    break;
  case 'leave':
    msg = data.User + '님이 퇴장했습니다.';
    break;
  }

  // <div> 태그를 생성하여 채팅 메시지를 넣어줌
  col = $('<div>').addClass('col-md-12').text(msg)
  row = $('<div>').addClass('row').append(col)
  list = $('#messageList').append(row)
  if (list.children().size() > 15)   // 채팅 메시지가 15개를 넘어가면
    list.find('div:first').remove(); // 메시지 삭제
});

앞의 Go 언어 코드와 마찬가지로 socket.io 객체에서 on 함수를 사용하면 각 상황마다 콜백 함수를 실행시킬 수 있습니다. 여기서는 첫 번째 매개 변수에 event를 설정하여 서버에서 이벤트가 왔을 때 콜백 함수을 실행시킵니다.

콜백 함수가 실행되면 Go 언어의 Emit 함수가 보낸 데이터가 매개변수로 넘어옵니다. 이 이벤트 데이터에서 EvtType을 판별하여 채팅 메시지와 사용자 입장, 퇴장 메시지를 만들어냅니다.

<div> 태그를 생성하여 채팅 메시지를 넣어줍니다. 그리고 HTML에서 ID가 messageList인 요소에 방금 생성한 <div> 요소를 추가하여 채팅 메시지를 출력시킵니다. 만약 messageList에 추가된 자식 <div> 요소가 15개를 넘어가면 첫 번째 자식을 삭제합니다.

채팅 메시지를 서버에 보내는 함수를 작성합니다.

// 채팅 메시지를 서버에 보내는 함수
send = function () {
  msg = $('#message').val()      // 입력 상자에서 메시지를 가져옴
  if (msg != '') {               // 메시지가 있으면
    socket.emit('message', msg); // 서버에 메시지를 보냄
    $('#message').val('');       // 입력한 데이터 삭제
  }
}

HTML에서 ID가 message인 입력 상자(<input>)에서 값을 가져온 뒤 값이 있으면 socket.io 객체의 emit 함수를 사용하여 서버에 메시지를 보냅니다. 그리고 메시지를 보낸 뒤 <input> 태그에서 입력한 데이터를 삭제합니다. 여기서 emit 함수의 첫 번째 매개변수에는 socket.io 메시지를 설정하며 두 번째 매개변수에는 데이터를 넣습니다. 이렇게 emit 함수로 보낸 메시지는 Go 언어 코드의 so.On("message", func(msg string) { }) 콜백 함수에서 받게 됩니다.

보내기 버튼과 엔터 키 입력으로 채팅 메시지를 보낼 수 있도록 jQuery 이벤트를 설정합니다.

// 보내기 버튼으로 메시지를 보냄
$('#send').click(function () {
  send()
});

// 엔터 키 입력으로 메시지를 보냄
$('#message').keyup(function(e) {
  if (e.keyCode == 13) { // 13이면 엔터 키
    send()
  }
});

HTML에서 ID가 send인 버튼에 click 함수를 사용하여 클릭 이벤트를 처리합니다. 그리고 message 입력 상자에 keyup 함수를 사용한 뒤 keyCode가 13일 때를 판별하여 엔터 키를 처리합니다. 각 이벤트가 발생하면 send 함수를 실행하여 서버에 채팅 메시지를 보냅니다.

다음은 전체 소스 코드입니다.

GOPATH/src/chat/index.html
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <title>Go Chatting</title>

  <!-- CDN의 Bootstrap 사용 -->
  <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">

  <!-- CDN의 jQuery 사용 -->
  <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

  <!-- 웹 브라우저용 socket.io JavaScript 파일 -->
  <script src="//cdn.socket.io/socket.io-1.3.3.js"></script>

  <style>
    .container {
      margin-top:30px;
    }
    #messageList {
      width:600px;
      height:320px;
      padding: 10px 10px 10px 10px;
    }
    #inputBox {
      width:600px;
    }
  </style>
</head>

<body>
  <div class="container">
    <div class="row">
      <div class="panel panel-primary" id="messageList"><!-- 대화 창 -->
      </div>
    </div>
    <div class="row">
      <div id="inputBox"><!-- 메시지 입력 창 -->
        <div class="input-group">  
          <input type="text" class="form-control" id="message" placeholder="Message">
          <span class="input-group-btn">
            <button class="btn btn-default" id="send" type="button">Send</button>
          </span>
        </div>
      </div>
    </div>
  </div>

  <script>
    var socket = io(); // socket.io 객체 생성

    // 서버에서 이벤트가 왔을 때 실행할 콜백 함수 설정
    socket.on('event', function (data) {
      var msg
      switch (data.EvtType) { // 이벤트 타입을 판별하여 메시지 생성
      case 'message':
        msg = data.User + ': ' + data.Text;
        break;
      case 'join':
        msg = data.User + '님이 입장했습니다.';
        break;
      case 'leave':
        msg = data.User + '님이 퇴장했습니다.';
        break;
      }

      // <div> 태그를 생성하여 채팅 메시지를 넣어줌
      col = $('<div>').addClass('col-md-12').text(msg)
      row = $('<div>').addClass('row').append(col)
      list = $('#messageList').append(row)
      if (list.children().size() > 15)   // 채팅 메시지가 15개를 넘어가면
        list.find('div:first').remove(); // 메시지 삭제
    });

    // 채팅 메시지를 서버에 보내는 함수
    send = function () {
      msg = $('#message').val()      // 입력 상자에서 메시지를 가져옴
      if (msg != '') {               // 메시지가 있으면
        socket.emit('message', msg); // 서버에 메시지를 보냄
        $('#message').val('');       // 입력한 데이터 삭제
      }
    }

    // 보내기 버튼으로 메시지를 보냄
    $('#send').click(function () {
      send()
    });

    // 엔터 키 입력으로 메시지를 보냄
    $('#message').keyup(function(e) {
      if (e.keyCode == 13) { // 13이면 엔터 키
        send()
      }
    });
  </script>
</body>
</html>

이제 소스 파일을 컴파일하여 실행해봅니다. github.com/googollee/go-socket.io 패키지는 인터넷에서 받아와야하므로 go get 명령을 먼저 실행한 뒤 go build 명령으로 컴파일합니다.

go get
go build

컴파일 된 실행 파일을 실행한 뒤 웹 브라우저를 두 개 열고 각각 http://127.0.0.1에 접속합니다. 저는 크롬과 IE를 사용했습니다.

그림 67-2 웹 브라우저에서 채팅 서버에 접속

두 웹 브라우저 모두 사용자 입장, 퇴장 상황이 표시되고, 한쪽에서 채팅 메시지를 입력하면 다른 웹 브라우저에도 표시되는 것을 볼 수 있습니다.

예제에서는 코드를 간단히 만들기 위해 채팅방을 하나만 만들었습니다. 채팅방을 여러 개 만들려면 먼저 사용자 가입 및 로그인 처리를 하고, 새 채팅방을 만들때 마다 Chatroom 함수를 고루틴으로 실행하여 처리하면 됩니다.


저작권 안내

이 웹사이트에 게시된 모든 글의 무단 복제 및 도용을 금지합니다.
  • 블로그, 게시판 등에 퍼가는 것을 금지합니다.
  • 비공개 포스트에 퍼가는 것을 금지합니다.
  • 글 내용, 그림을 발췌 및 요약하는 것을 금지합니다.
  • 링크 및 SNS 공유는 허용합니다.

Published

2015-06-01