このページで学習出来る事
新人エンジニアとプログラミングタイムトライアルで作成した簡易チャットです。PHP/Javascript[jQuery/Ajax]で作られており、非常にシンプルですので、非同期通信の手順や仕組みが分かりやすいと思います。
ちなみにプログラミングタイムトライアルの結果は38分44秒で勝利でした。(レギュレーションは関数のみ検索可能。送信ボタンを押してメッセージが書き込まれたのを確認して終了です。ソースコードは公開用に少し綺麗にしてあります)
学習内容
-
非同期簡易チャットの作り方
-
非同期処理のPHP側やJavaScript側の動きと記述内容
この学習で使用するソースコード類はここからダウンロードできます。
実際に動いているチャットはこちらから確認できます。
サンプルコード[HTML]
まずはhtmlファイルからですが、htmlファイルに関しては[jquery]や[javascript]の読み込みに注意する感じで、それ以外は特別な書き方はしていません。
チャットのメッセージ部分をテキストエリアかボックスで行こうか迷いましたが、ここでは[div]のボックスにメッセージを書き込むことにしています。
<!doctype html>
<html lang="jp">
<head>
<meta charset="utf-8">
<title>Taru-Chat</title>
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script src="./chat.js"></script>
<link href="./chat.css" rel="stylesheet">
</head>
<body>
<p>たるチャットです。PHP/Javascript[jQuery/Ajax]で動いています</p>
<p></p>
<form method="post" onsubmit="writeMessage(); return false;">
<input id="message" name="message" type="text" value="" />
<input type="button" value="送信" onclick="writeMessage()">
</form>
<div id="messageTextBox"></div>
</body>
</html>
サンプルコード[JavaScript]
続いて[Javascript]の処理になります。
[送信]をクリックしたときに実行される[writeMessage]と、DOMの更新がされたときに実行される[readMessage]が主要機能です。
非同期での処理間隔ですが、今回は3秒に設定してあります。これはAさんが書き込んだ場合、Bさんが何も処理をしなくても、書き込みから3秒後に表示されるというものです。
その非同期処理に関しては[$(document).ready]にてDOMの更新が発生した場合に、[readMessage]を3秒間隔で読み込んでいます。
function readMessage() {
$.ajax({
type: 'post',
url: './message.log'
})
.then(
function (data) {
log = data.replace(/[\n\r]/g, "<br />");
$('#messageTextBox').html(log);
},
function () {
alert("読み込み失敗");
}
);
}
function writeMessage() {
$.ajax({
type: 'post',
url: './main.php',
data: {
'message' : $("#message").val()
}
})
.then(
function (data) {
readMessage();
$("#message").val('');
},
function () {
alert("書き込み失敗");
}
);
}
$(document).ready(function() {
readMessage();
setInterval('readMessage()', 3000);
});
コードの解説 JavaScript
‘リクエスト種類とファイルの読み込み先が設定してあります。
$.ajax({
type: ‘post’,
url: ‘./message.log’
})
‘処理が成功した場合と失敗した場合の内容が記載してあります。
.then(
function (data) {
log = data.replace(/[\n\r]/g, “<br />”);
$(‘#messageTextBox’).html(log);
},
function () {
alert(“読み込み失敗”);
}
);
log = data.replace(/[\n\r]/g, “<br />”); ’ログファイルから取得した改行コードをhtmlに反映させるため置換処理をしています。
$(‘#messageTextBox’).html(log); '[div]側に取得したデータを表示する記述です。
‘リクエストの種類と書き込み処理をするPHPファイル、書き込まれた内容を取得する内容となっています。
$.ajax({
type: ‘post’,
url: ‘./main.php’,
data: {
’message’ : $(“#message”).val()
}
})
‘DOMが更新された場合にインターバル期間を置いて書き込む処理をしています。
$(document).ready(function() {
readMessage();
setInterval(‘readMessage()’, 3000);
});
サンプルコード[PHP]
次にPHP側の処理ですが、最初にAjax以外からのリクエストが来た場合に終了する内容が記述されており、その後、ログファイルを中身を取得し、入力されたデータの追記処理をしています。
ログ数は200を上限として、それ以降は更新処理となるようにしています。
<?php
$count = 0;
$strMsg = '';
$request = '';
if (isset($_SERVER['HTTP_X_REQUESTED_WITH'])) {
$request = strtolower($_SERVER['HTTP_X_REQUESTED_WITH']);
}
if ($request !== 'xmlhttprequest') {
exit;
}
$message = '';
if (isset($_POST['message']) && is_string($_POST['message'])) {
$message = htmlspecialchars($_POST['message'], ENT_QUOTES);
}
if ($message == '') {
exit;
}
$fp = fopen('message.log', 'r');
if (flock($fp, LOCK_SH)) {
while (!feof($fp)) {
if ($count > 200) {
break;
}
$strMsg = $strMsg . fgets($fp);
$count = $count + 1;
}
}
flock($fp, LOCK_UN);
fclose($fp);
$strMsg = date("Y-m-d H:i:s") . ' - ' . $message . "\n" . $strMsg;
file_put_contents('message.log', $strMsg, LOCK_EX);
?>
コードの解説 PHP
‘Ajaxからのリクエストかを確認しています。
if (isset($_SERVER[‘HTTP_X_REQUESTED_WITH’])) {
$request = strtolower($_SERVER[‘HTTP_X_REQUESTED_WITH’]);
}
‘POSTリクエストで送られてきたフォームの中身を取得しています。
if (isset($_POST[‘message’]) && is_string($_POST[‘message’])) {
$message = htmlspecialchars($_POST[‘message’], ENT_QUOTES);
}
‘ログファイルをロックしてからログファイルの読み込み処理を行っています。
‘200行をまでは追記していきますが、それ以降は更新処理となるようにログファイルをを読み込みしないようにしています。
$fp = fopen(‘message.log’, ‘r’);
if (flock($fp, LOCK_SH)) {
while (!feof($fp)) {
if ($count > 200) {
break;
}
$strMsg = $strMsg . fgets($fp);
$count = $count + 1;
}
}
‘フォームから入力されたデータに時間を加えて、ログファイルへ書き込み処理をしています。
$strMsg = date(“Y-m-d H:i:s”) . ‘ – ‘ . $message . “\n” . $strMsg;
file_put_contents(‘message.log’, $strMsg, LOCK_EX);
最後に
以上で簡易チャットの作り方解説となります。タイムアタック用で作成したものですので、かなりシンプルに作られていると思います。
これにユーザとCookie処理を加えれば、簡単なLINEクローンが出来るかと思います。
最近ですと[Node.js]と[Vue.js]で、同期処理の取れたサイトも簡単に作れてしまいますので、技術の進歩は早いものです。
ただ、こういったのは最新のツール等はプログラマを引退しても、引き続き勉強していきたいものですね。