채팅 프로그램
아래에 채팅 서버 프로그램(소스포함)을 등록해 놓았습니다.
본 글에서는 홈페이지에서 동작하는 채팅 프로그램(클라이언트)를 올려드립니다.
다음은 홈페이지에서 적용되고 있는 모습니다. ( 디자인적인 면에서 좀 떨어지죠? )
WS ( WebSocket ) 이전에는 XHR (Ajax 의 모태) 이나 Long Pulling(COmet) 등을 사용해 왔지만 WS 는 근본적으로 틀린것입니다.
말 그대로 소켓 통신이 가능합니다. 이로 인한 장점 또는 차이점은 본 글에서 다 설명을 하기가 어렵습니다.
HTML5 는 십여년간 베타버젼을 거쳐 앞으로 2년 안에 정식 버젼으로 책정한다는 계획입니다.
WS 는 HTML5 의 Connectivity 에 해당하는 것으로 현재 Draft 이며 거의 모든 Major 브라우저의 최신 버젼에서 지원합니다.
WS 가 표준이 될 것이라는 것에는 어느 누구도 의견이 없습니다.
그리고 HTML5 에서 소켓 통신이 가능하므로서 기존의 C/S 의 모든 것이 웹 브라우저 안에서 펼쳐질 수 있습니다.
채팅 프로그램만 해도 그렇습니다.
채팅방에서 "안녕하세요" 라는 다섯 글자를 다른 사람들에게 보내기 위해서는 적게는 수십 Kilo Bytes 에서 수 Mega Bytes 의 대역폭을 차지해야 했습니다.
왜 한글 5 글짜가 수십 메가까지 차지하냐구요? 지금 답을 가르쳐 드리면 재미 없겠죠?
WS 와 XHR 의 차이점에 대한 문서를 찾아보시면 쉽게 해답을 얻으 실 수 있을 것입니다.
--------------------- 채팅 클라이언트 소스 -------------------------
SAPCMS 1.2 버젼을 바탕으로 만들었습니다. 적절하게 응용하여 다른 홈페이지에 적용 할 수 있습니다.
SAPCMS 는 저희가 직접 개발하였으며 현재 필고 사이트가 SAPCMS 로 만들어졌습니다.
SAPCMS GPL 오픈 소스 소프트웨어로서 배포됩니다.
============= [ HTML ] ==============
<script src="
file.withcenter.co.kr:8083/socket.io/socket.io.js"></script><?php
widget_css(__FILE__);
widget_javascript(__FILE__);
?>
<script>
$pchat_id = "<?=login('id')?>";
$pchat_name = "<?=login('nickname')?>";
$language = "<?=etc::user_language()?>";
</script>
<div class='pchat'>
<div class='display'></div>
<form class='chat'>
<br>
<input type='text' name='message' value=''><input type='submit' value='Send'>
<br>
<button class='roomlist'>Room Info</button>
<input type='text' name='room_name' value='' style='width:100px;'>
<a href='javascript:void(0);' class='room_join'>Join</a>
</form>
</div>
============ [ CSS ] ================
.pchat .display { height: 200px; width: 100%; overflow:auto; border: 1px solid blue; }
.pchat .display .notice { padding: 10px; }
.pchat .display .notice .name { font-weight: bold; }
.pchat .display .message .name { margin-right: 6px; }
.pchat .display .message .name:after { content:' : '; }
.pchat .display .room_name { cursor:pointer; }
============== [ JAVASCRIPT ] ==============
var socket = io.connect('file.withcenter.co.kr:8083');
socket.on('chat', function(data){
chat_log("Received:");
chat_log(data);
if ( data.action == 'enter' ) {
if ( $language == 'ko' ) chat_notice(data.name, "님이 입장하였습니다.");
else chat_notice(data.name, "has entered.");
}
else if ( data.action == 'leave' ) {
if ( $language == 'ko' ) chat_notice(data.name, $sir + ' ' + data.to + ' (으)로 이동하였습니다.');
else chat_notice(data.name, "has move to " + data.to );
}
else if ( data.action == 'message' ) {
chat_message(data.name, data.value);
var $box = $('.display');
$box.scrollTop( $box.height() );
}
else if ( data.action == 'room list' ) {
entered = JSON.parse(data.entered);
for ( var i in entered ) {
var room_name = entered[i].room;
room_name = "
" + room_name + "";
if ( $language == 'ko' ) chat_notice(entered[i].name, '(' + entered[i].id + ") 님이 " + room_name + " 에 있습니다.");
else chat_notice(entered[i].name, '(' + entered[i].id + ") is in " + room_name + ".");
}
}
else if ( data.action == 'join' ) {
if ( $language == 'ko' ) chat_notice(data.name, '님이 들어왔습니다.');
else chat_notice(data.name, '(' + data.id + ') has entered in ' + data.value);
}
});
socket.on('connect', function () {
chat_log("Connected successfully...");
var msg = {};
msg['id'] = $pchat_id;
msg['name'] = $pchat_name;
msg['action'] = 'enter';
var data = JSON.stringify(msg);
send(msg);
});
socket.on('connecting', function () {
chat_log("Trying to connect...");
});
socket.on('disconnect', function () {
chat_log("Disconnected....");
});
socket.on('connect_failed', function () {
chat_log("Connection failed...");
});
socket.on('error', function () {
chat_log("Error...!");
});
socket.on('reconnect_failed', function () {
chat_log("Reconnection failed...");
});
socket.on('reconnect', function () {
chat_log("Reconnection succefully...");
});
socket.on('reconnecting', function () {
chat_log("Reconnecting....");
});
function chat_log(msg)
{
console.log(msg);
}
function chat_notice(name, msg)
{
$('.display').append("
" + name + ""+msg+"
");
}
function chat_message(name, msg)
{
$('.display').append("
" + name + ""+msg+"
");
}
function send(data)
{
chat_log('Sending: ');
chat_log(data);
socket.emit('chat', data);
}
$(function(){
$chat = $('form.chat');
$($chat).submit(function(){
$v = $('[name=message]').val();
if ( $v ) {
var msg = {};
msg['action'] = 'message';
msg['id'] = $pchat_id;
msg['value'] = $v;
send(msg);
$('[name=message]').val('');
$('[name=message]').focus();
}
return false;
});
$('.roomlist').click(function(){
var msg = {};
msg['action'] = 'room list';
msg['id'] = $('[name=id]').val();
send(msg);
});
$('form.chat .enter').click(function(){
var msg = {};
msg['id'] = $pchat_id;
msg['name'] = $pchat_name;
msg['action'] = 'enter';
var data = JSON.stringify(msg);
send(msg);
});
$('.room_join').click(function(){
var msg = {};
msg['action'] = 'join';
msg['id'] = $pchat_id;
msg['value'] = $('[name=room_name]').val();
send(msg);
});
$('body').on('click', '.pchat .display .room_name', function(){
var v =$(this).text();
var msg = {};
msg['action'] = 'join';
msg['id'] = $pchat_id;
msg['value'] = v;
send(msg);
});
});
@알림 : 코멘트를 작성하시려면 로그인을 하십시오.