SHIROのIchigoJam日記

マイコン「IchigoJam」(イチゴジャム)の電子工作とプログラミングをメインに

Ichigoチャット(双方向対応版)

IchigoJam+MixJuice(Wi-fiボード)でチャットを体験する、プログラミング教室用Webサイトの作り方です。
IchigoJamでメッセージを入力すると、Webサイトで一覧表示されます。
ペアで互いにやり取りすることもできます。
f:id:shiro0922:20210830155820j:plain

f:id:shiro0922:20210830155849j:plain

f:id:shiro0922:20210830170024p:plain

★注意★ 簡単なプログラムなのでセキュリティを一切考えていません。教室を行う時だけサイトを設置して、終わったら削除や移動をするようにしてください。サイトを置きっぱなしにすると、悪意のある人にアクセスされてデータベースを破壊されたり乗っ取られたりする危険性があります。

上記の乗っ取りなどを防ぐために、教室内にサーバーPCとWi-fiルーターを置いて、ローカルネット環境で動かすことをお勧めします。

準備

■Webサーバー

PHPMySQLが動くWebサーバーを用意します。
新規に作るならXAMPPなどを利用すると良いでしょう。

MySQLのデータベース、テーブル

phpMyAdminなどを使って、チャットのデータを記録するデータベース(例「chat」)を新規に作ります。
その中に「chat」テーブルを作成して、「time」列(datetime型)、「userid」列(text型)、「message」列(text型)、「readsw」列(int型)を作ります。

■ページの設置

www.example.jp/dir/(サイトのアドレス)内に、以下のWebページファイルを設置します。

db_login.php

ログイン情報を入れるファイルです。
dbnameはデータベース名、usernameはデータベースにアクセスするユーザー名、passwordはそのユーザーのパスワードを記述します。

<?php
$db_host='localhost';
$db_database='dbname';
$db_username='username';
$db_password='password';
?>
index.php

チャットの一覧表を表示するWebページです。5秒ごとに表示が自動更新されます。
行表示の順番を「時間順」(時間昇順)/「最新順」(時間降順)で切り替えられます。

<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf8">
<title>Ichigoチャット</title>
<link rel="stylesheet" href="styles.css" type="text/css" />
<meta http-equiv="refresh" content="5; URL=">
</head>

<body>
<h1>Ichigoチャット</h1>

<?php

// ログイン情報のインクルード
include('db_login.php');

// データベースサーバーへ接続
$connection = mysqli_connect($db_host, $db_username, $db_password, $db_database);
if (!$connection) {
	die ("DB接続エラー<br />". mysql_error());
}

$strSort = "0";
if (isset($_GET['SORT'])) {
	$strSort = $_GET['SORT'];
}

// === chatテーブルからタイムライン ===

// タイムラインクエリを作成
$query = "SELECT * FROM chat ORDER BY time";
if ($strSort == "1") {
	$query = "SELECT * FROM chat ORDER BY time DESC";
}

// クエリを実行
$result = mysqli_query($connection, $query);
if (!$result) {
	die ("DBクエリエラー<br />". mysql_error());
}

// 結果から一覧表を表示
echo "<table>\r\n";
echo "<tr><th class='time'>Time</th><th class='userid'>UserID</th><th>Message</th><th>ReadSW</th></tr>\r\n";

foreach ($result as $row) {
	echo "<tr><td>" . $row['time'] . "</td><td>" . $row['userid'] . "</td><td>" . $row['message'] . "</td>";
	if ($row['readsw']=="0") {
		echo "<td>未読</td>";
	} else {
		echo "<td>既読</td>";
	}
	echo "</tr>\r\n";
}

echo "</table>\r\n";

echo "<form action='index.php'>\r\n";
echo "<select name='SORT'>\r\n";
if ($strSort == "0") {
	echo "<option value='0'>時間順</option>\r\n";
} else {
	echo "<option value='0' selected>時間順</option>\r\n";
}
if ($strSort == "1") {
	echo "<option value='1'>最新順</option>\r\n";
} else {
	echo "<option value='1' selected>最新順</option>\r\n";
}
echo "</select>\r\n";
echo "<input type='submit' value='再ソート'>\r\n";
echo "</form>\r\n";

// === 終了処理 ===

// データベース接続を閉じる
mysqli_close($connection);

?>

</body>
</html>
styles.css

一覧表ページの見栄えを設定するスタイルシートです。お好みで改造してください。

html {
background-color: #FFFFFF;
font-family: sans-serif;
}

body {
margin: 20px auto 10px auto;
width: 920px;
text-align: center;
font-size: middle;
line-height: 1.3em;
color: #000000;
}

h1 {
height: 40px;
margin: 0px;
padding-left: 10px;
font-size: 18pt;
line-height: 40px;
color: #000000;
}

table {
margin: 10px auto 10px auto;
border-style: solid;
border: 2px solid #8888ff;
}

th {
text-align: center;
font-size: 14pt;
padding: 2px;
border: 1px solid #8888ff;
}

td {
font-size: 14pt;
padding: 2px;
border: 1px solid #8888ff;
}
send.php

IchigoJam+MixJuiceから送られてきたチャットのデータを、データベースに書き込むWebページです。
「receive.log」にアクセスログが出力されます。もしデータベース接続エラーなどが出た場合は、このログを参照してください。
IchigoJam+MixJuiceから来る文字列は文字コードがShift-JISなのですが、このページ内でUTF-8に変換してデータベースに記録しています。これでカタカナもちゃんと記録・表示されます。

<?php

// ログイン情報のインクルード
include('db_login.php');

// データ受信

if (isset($_GET['MES'])) {

	$strID = $_GET['ID'];
	$strMes = $_GET['MES'];
	$strMes = mb_convert_encoding($strMes, "UTF-8", "SJIS");

	// ログファイルの相対パス
	$strDataFilePath = 'receive.log';

	// ログファイルを追記モードでオープン
	$fp = fopen($strDataFilePath, "a");

	// 日付、時刻を取得
	date_default_timezone_set('Asia/Tokyo');
	$dt = new DateTime();
	$strDateTime = $dt->format('Y-m-d H:i:s');

	// 受信した値をログファイルに書き込み
	fwrite($fp, $strDateTime . ',Send,ID=' . $strID . ',Mes=' . $strMes . "\r\n");

	// データベースサーバーへ接続
	$connection = mysqli_connect($db_host, $db_username, $db_password, $db_database);
	if (!$connection) {
		fwrite($fp, "DB接続エラー\r\n");
	}

	// === chatテーブルを更新 ===

	// データ更新クエリを作成
	$query = "INSERT INTO chat SET time='$strDateTime', userid='$strID', message='$strMes', readsw='0'";
	
	// クエリを実行
	$result = mysqli_query($connection, $query);
	if (!$result) {
		fwrite($fp, "データ更新エラー\r\n");
	}

	// === 終了処理 ===

	// データベース接続を閉じる
	mysqli_close($connection);

	// ログファイルポインタをクローズ
	fclose($fp);

}

?>
read.php

IchigoJamからのリクエストに応じて、データベースからチャットの文字列を出力するWebページです。
「receive.log」にアクセスログが出力されます。もしデータベース接続エラーなどが出た場合は、このログを参照してください。

<?php

// ログイン情報のインクルード
include('db_login.php');

// データ受信

if (isset($_GET['ID'])) {

	$strParas = $_GET['ID'];
	
	$strID = $strParas;
	
	// ログファイルの相対パス
	$strDataFilePath = 'receive.log';

	// ログファイルを追記モードでオープン
	$fp = fopen($strDataFilePath, "a");

	// 日付、時刻を取得
	date_default_timezone_set('Asia/Tokyo');
	$dt = new DateTime();
	$strDateTime = $dt->format('Y-m-d H:i:s');

	// 受信した値をログファイルに書き込み
	fwrite($fp, $strDateTime . ',Request,ID=' . $strID . "\r\n");

	// データベースサーバーへ接続
	$connection = mysqli_connect($db_host, $db_username, $db_password, $db_database);
	if (!$connection) {
		fwrite($fp, "DB接続エラー\r\n");
	}

	// === chatテーブルから読み取り ===

	// データ読み取りクエリを作成
	$query = "SELECT * FROM chat WHERE userid='$strID' AND readsw='0' ORDER BY time LIMIT 1";

	// クエリを実行
	$result = mysqli_query($connection, $query);
	if (!$result) {
		fwrite($fp, "データ読み取りエラー\r\n");
	}

	foreach ($result as $row) {
		if ($row['readsw'] == "0") {
			
			$strMes = mb_convert_encoding($row['message'], "SJIS", "UTF-8");
			echo $strMes . "\r\n";
			$query = "UPDATE chat SET readsw='1' WHERE userid='$strID' AND readsw='0' ORDER BY time LIMIT 1";
			$result = mysqli_query($connection, $query);
			if (!$result) {
				fwrite($fp, "データ変更エラー\r\n");
			} else {
				fwrite($fp, $strDateTime . ',Update,ID=' . $strID . ',ReadSW=1' . "\r\n");
			}
			
		}
	}

	// === 終了処理 ===

	// データベース接続を閉じる
	mysqli_close($connection);

	// ログファイルをクローズ
	fclose($fp);

}

?>

■ページの動作テスト

PCのブラウザで「www.example.jp/dir/index.php」を開くと、一覧表ページが表示されます。

ブラウザの別ウインドウで、書き換えページへ以下のようにアクセスすると、メッセージを送信できます。

www.example.jp/dir/send.php?ID=UEDA01&MES=ABCDE

「UEDA01」はユーザーID、「ABCDE」はメッセージの文字列です。
メッセージはカタカナも使えますが、IchigoJamの記号文字(人形・音符・イチゴマークなど)は使えません。
メッセージを送信した後、一覧表ページで受信されていることを確認してください。

教室での使い方

(1)IchigoJam+MixJuiceを動かして、Wi-fiアクセスポイントに接続します。

?”MJ APC ssid password”

ssidWi-fiアクセスポイントのSSID、passwordはパスワードです。ちゃんと接続するまで1分ほど待ってください。
(一度接続するとその設定が記憶され、次回は入力しなくても自動接続されます)

(2)教室内で、メッセージをやり取りするペアを決めます。

(3)以下のチャットプログラムを入力して実行します。

10 CLS
20 ?:?"(SEND)"
30 INPUT "",M
40 A=#900+POS()-33:L=0
50 A=A+1:C=PEEK(A)
60 IF C>0 L=L+1:[L]=C:GOTO 50
70 IF L=0 GOTO 130
80 ?"MJ GET www.example.jp/dir/SEND.PHP?ID=UEDA01&MES=";
90 FOR C=1 TO L
100 D=[C]:IF D=32 D=95
110 ?CHR$(D);
120 NEXT:?:WAIT 180
130 CLK
140 ?:?"MJ GET www.example.jp/dir/READ.PHP?ID=UEDA02"
150 WAIT 60:C=INKEY()
160 IF !C GOTO 20
170 ?:?"(READ)"
180 ?CHR$(C);:C=INKEY()
190 IF C GOTO 180
200 ?:GOTO 20

80行の「UEDA01」は自分のユーザーID、140行の「UEDA02」はペア相手のユーザーIDです。それぞれのIchigoJamで別のIDにしてください。

f:id:shiro0922:20210830155849j:plain

  • 実行すると「(SEND)」(送信)と表示されるので、1行でメッセージを入力して、Enterキーを押すと送信されます。(2行以上入力すると最後の行だけ送信されます)。
    • メッセージはカタカナも使えますが、IchigoJamの記号文字(人形・音符・イチゴマークなど)は使えません(文字化けします)。
    • スペース(空白)は「_」(下線、アンダースコア)に変換されて送信されます。
  • 送信後は、「(READ)」(受信)と表示されて、ペア相手のメッセージを受信します。未読メッセージのうちで一番古いものが1件受信されます。未読が無い時は受信しません。
  • 「(SEND)」に戻って、くり返します。
  • 「(SEND)」の入力待ちでEnterキーだけ押すと、送信をスキップして「(READ)」へ行きます。ペア相手が複数のメッセージを投稿している時は、この手順で順番に未読分を受信してください。

(4)PCのブラウザで一覧表ページ「www.example.jp/dir/index.php」を開くと、チャットの一覧が確認できます。


この画面をスクリーンなどに映して、教室内で共有するといいでしょう。
※「ReadSW」は、メッセージが登録された時は「未読」、送信先の相手がそのメッセージを読み取ると「既読」になります。

●進め方としては、プログラミングを2段階にしても良いです

まずプログラムの送信部分を入力します。

10 CLS
20 ?:?"(SEND)"
30 INPUT "",M
40 A=#900+POS()-33:L=0
50 A=A+1:C=PEEK(A)
60 IF C>0 L=L+1:[L]=C:GOTO 50
70 IF L=0 GOTO 130
80 ?"MJ GET www.example.jp/dir/SEND.PHP?ID=UEDA01&MES=";
90 FOR C=1 TO L
100 D=[C]:IF D=32 D=95
110 ?CHR$(D);
120 NEXT:?:WAIT 180
130 CLK
200 ?:GOTO 20

これでメッセージを送信して、一覧表画面で確認します。
次に受信部分を追加入力します。

140 ?:?"MJ GET www.example.jp/dir/READ.PHP?ID=UEDA02"
150 WAIT 60:C=INKEY()
160 IF !C GOTO 20
170 ?:?"(READ)"
180 ?CHR$(C);:C=INKEY()
190 IF C GOTO 180

これでペアで送受信することができます。