PHP+jQuery+MySQLでCometっぽいチャットを実装する

Cometとはサーバで発生したイベントをクライアントからの要請なしにクライアントに送信することができる仕組み。

Comet – Wikipedia

この仕組みというか考え方を使い、チャットサイトを作成してみた。
既に同じ仕組みを考案している人がいるが、参考にしてテストしてみた所、MySQLへのコネクションがバックグラウンドで動く事は良いが、ブラウザを終了しても、その処理が生き続けてしまった。ようするにMySQLを再起動しないと処理が完全に終了しなくなった。

参考サイト:
PHPとjQueryでCometっぽいモノを実装する

 

HTMLのサンプルコード

基本はこれだけ

[html]

<div id="chat_log">
<div id="view"></div>
</div>

<textarea id="chat_data" name="chat_data" rows="2″ cols="55″ >
</textarea>
<input type="button" id="data_submit" value="" />

[/html]

 

jQueryのサンプルコード

投稿時は$.postでデータを送り、メッセージは$.getJSONで取得する。
$.getJSONを使う理由は、戻り値で判定を行う際に色々出来るから。単に取得したデータを表示するだけだと、$.postでも$.getでも良い。そして取得したメッセージを<div id="view"></div>に表示。

go_bottom()はHTMLサンプルコードにある様に<div id="chat_log"></div>で指定した表示範囲内(cssでheightやoverflowなどを利用した場合)でスクロールバーが表示された時、通常ならメッセージを読み込んだらスクロールバーが最上部に、最新メッセージは最下部に表示されてしまうので、いちいちスクロールバーを最下部まで持っていかなくてはならない。それを防ぐために、自動的にスクロールバーを最下部に持っていく仕掛け。

あと、あくまでもCometっぽい仕掛けなので、最新記事はSetIntervalで5秒間隔で取得する。
参考にしたサイトではwhileにて無限ループをあえて発生させているが、これがMySQLだとselectを発行し続けてしまうので、MySQLを利用した場合は合わないと考えられる。実際、mysql_query.logには1秒間隔でselectが発行されていた。ブラウザを閉じても。

[javascript]

$(document).ready(function(){
var $view = $('#view’),
$chat_data = $('textarea[name="chat_data"]’);

/* 投稿 */
$(“#data_submit").bind(“click",function(){
if($(“#chat_data").val() != “"){
var chat_data = $(“#chat_data").val();
$.post(“comet.php?mode=add", {chat_data: $chat_data.val()},function(data){
getData();
$chat_data.val(");
go_bottom();
});
}
});

/* データ取得 */
function getData() {
var dt = new Date;
var now = dt.getTime();
var chat_data = $(“#chat_data").val();
$.getJSON(“comet.php?mode=view&date="+now,function(data){
$view.html(data);
go_bottom();
});
}

/* スクロールバーを一番下にする */
function go_bottom(){
var chat_log = document.getElementById('chat_log’);
chat_log.scrollTop = chat_log.scrollHeight;
}

getData();
setInterval(getData,5000);
});

[/javascript]

 

PHPのサンプルコード

データを取得・追加する処理は省略。comet.phpとして保存。

[php]

<?php
/* データ取得 */
function getData(){
// データを取得する処理を記述
return $data;
}

/* データ追加 */
function pushData($data) {
// データを追加する処理を記述
return getData();
}

if(isset($_GET['mode’]) || isset($_POST['mode’])){
// モード振り分け
switch($_GET['mode’]){
// データ取得
case 'view’:
$data = getData();
break;

// データ保存
case 'add’:
$data = mysql_real_escape_string($_POST['chat_data’]);
$data = pushData($data);
break;
}

// 結果を表示
$json = new Services_JSON;
$data =  nl2br($data);
$encode = $json->encode($data);
header(“Content-Type: text/javascript; charset=utf-8");
print $encode;
}
?>

[/php]

 

出来あがったチャットサイトがここです。