Jquery+PHPで簡易チャットを作る

2014-03-07

こちらで新しいjQueryチャットの記事を書きました。宜しければどうぞ!

パソコンを始めた当時はWEBチャットが盛んで、毎夜遅くまで遊んでいました。最近はSNSやLINE、Skypeなどが有りますので、もうそう需要は無いと思うのですが、ちょっと作ってみました。

サンプル
ダウンロード date/chat.logのパーミッションを777へ

今回作成したものは、どちらかと言うとスマートフォン向けになっています。LINEやSkypeと同じように、下部に投稿フォームが有り、ログが下へ埋まっていくスタイルです。HTML上で動きますので、デザインなどはご自由にどうぞ。

chat.js

/*
 * スマートフォン向け 簡易チャット
 * 
 * https://studio-key.com/
 * Copyright(c)2013 STUDIO KEY Allright reserved.
 * 
 */

$(document).ready(function(){
   $("#chatwrap").hide(); //初回ロード時はチャット枠を非表示
      logAll(); //ログをロード
      
   $("#str").focus(function(){ 
      scTarget(); 
   });
      
/*
 * 名前送信
 */
   $("#button2").click(function(){ 
      if( !$("#name").val() ) return false;
      
    //HTMLタグを除去
      var name = $('<div>'+$("#name").val()+'</div>').text();
      
    //jquery.cookie.jsで名前と色をクッキーに記録
      $.cookie("CHAT_NAME", name, { expires: 7 });
      $.cookie("CHAT_COLOR", $("#color").val(), { expires: 7 });
      
      writeLog(name+' : 入室しました','roomin');

      $("#chatwrap").show(); //チャット枠を表示
      $("#f3").hide(); //名前枠を非表示
   });
   
/*
 * チャット送信
 */
   $("#button1").click(function(){ 
      var str = $("#str").val();
      if(str){
         writeLog(str,null); 
      }else{
         //名前無いとき *エラー表示など
      }
   });
   
 /*
  * チャットを記録する
  */
   function writeLog(str,type){
         $.ajax({
            type: "POST",
            url: "lib/log.php",
            data: "type="+type+"&str="+str,
            success: function(xml){
               $(xml).find("item").each(function(){
                  loadLog();
                  $("#str").val('');
               });
            }
         }); 
   }
   
 /*
  * ログをリロードする
  */
   function logAll(flag){
      loadLog();
      setTimeout(function(){
         logAll();
      },10000); //リロード時間はここで調整
   }
   
 /*
  * 全ログを表示
  */
   function loadLog(){
      $('#Log ul li').remove(); //一旦空にする
         $.ajax({
            async: false,
            type: "POST",
            url: "lib/log.php",
            data: "type=log",
            success: function(xml){
               $(xml).find("item").each(function(){
                  var chat  = $(this).find("log").text();
                  var name  = $(this).find("name").text();
                  var color = $(this).find("cr").text();
                  var date = $(this).find("date").text();
                  $("<li></li>").html('<li style="color:'+color+'">'+name+' <div class="log">'+chat+'</div> <div class="date">'+date+'</div>').appendTo("#Log ul");
                  scTarget();
               });
            }
         }); 
   }

/*
 * 画面を最下部へ移動させる
 */
  function scTarget(){
     var pos = $("#end").offset().top; 
     $("html, body").animate({ 
        scrollTop:pos 
     }, 0, "swing"); //swingで0が良さそう
        return false;
  }
   
});

やることは

  1. 名前を送信したときにクッキーに記録し、管理人メッセージをログに記録
  2. チャットを送信したときにログに記録し、ログをリロード *setTimeout
  3. 指定秒数でログをリロード
  4. イベント発生時にログ表示部分を最下部まで移動させる

こんな感じです。当初は投稿時に単純に<li>へ要素を追加していけばいいや!と思っていたのですが、チャットなので複数人利用を考えると、やはりログのリロードが必要ですよね。ですので、イベント発生時には全ログで書き変えています。

log.php

<?php
/*
 * スマートフォン向け 簡易チャット
 * 
 * https://studio-key.com/
 * Copyright(c)2013 STUDIO KEY Allright reserved.
 * 
 */

session_start();

if(!$_POST) exit;

$max   = 50; //記録件数
$file  = '../data/chat.log';  //ログ記録ファイル
$admin = '管理人'; //管理人の名前

/*
 * チャットをファイルに書き込む
 */
function writeLog($str,$name,$color){
   global $file,$max;
   
   $bbsLog = file($file);
   $fp     = fopen($file,"w"); 
   flock($fp,2);
   $line = time().'<>'.$name.'<>'.$str."<>".date('Y/m/d H:i')."<>".$color."<>\n"; //最新ログを書き込む
   fputs($fp,$line);
   for($i=0; $i < count($bbsLog); $i++){ //既存ログを書き込む
      if( $i == $max) break; //指定件数になったら停止
      fputs($fp,$bbsLog[$i]);
   }
   flock($fp,3); 
   fclose($fp);
}


header("Content-type: application/xml");
echo '<?xml version="1.0" encoding="UTF-8" ?> ' . "\n";

/*
 * 全ログを取り出す
 * 
 */
if($_POST['type'] == 'log') {
   $bbsLog = file($file);
   $bbsLog = array_reverse($bbsLog);
   
?>
<rss>
<?php
   foreach( $bbsLog AS $row):
      $log = explode("<>",$row);
?>
  <item xml:space="preserve">
      <name><?php echo $log[1]; ?></name>
      <log><?php echo $log[2]; ?></log>
      <date><?php echo $log[3]; ?></date>
      <cr><?php echo $log[4]; ?></cr>
  </item>
<?php endforeach; ?>
</rss>

<?php
}

/*
 * 入室メッセージを記録する
 * 
 */
elseif($_POST['type'] == 'roomin') {
   $str = strip_tags($_POST['str']); //HTMLタグを除去
   $str = htmlspecialchars($str , ENT_QUOTES , "UTF-8"); // 特殊文字を HTML エンティティに変換する
   writeLog($str,$admin,'#666');
}
/*
 * 送信されたチャットをファイルに記録する
 * 
 */
else{
   $str = strip_tags($_POST['str']); //HTMLタグを除去
   $str = htmlspecialchars($str , ENT_QUOTES , "UTF-8"); // 特殊文字を HTML エンティティに変換する
   writeLog($str,$_COOKIE['CHAT_NAME'],$_COOKIE['CHAT_COLOR']);
?>
<rss>
  <item xml:space="preserve">
      <log><?php echo $str; ?></log>
      <name><?php echo $_COOKIE['CHAT_NAME']; ?></name>
  </item>
</rss>
<?php
exit;
}

?>

特に変わった事はしていません。送信されたチャットをchat.logに記録したり、全ログを取り出したりしつつ、XMLファイルとして書き出しています。

リロードをもう少し何とかしたいのですが、方法は無いんでしょうかね・・・投稿時に閲覧してる人にプッシュ・・って訳にはいきませんし。