リアルタイムデータの送受信
チャンネル(room.plugin)を使って同じチャットルームの参加者どうしでチャットメッセージ以外のデータをやり取りし、受け取ったデータを検証する流れを説明します。
最終更新 2026年10月17日
チャンネルを使うと、同じチャットルームにいる人どうしで、チャットメッセージ以外のデータをリアルタイムにやり取りできます。一緒に見る機能、ゲーム、投票のように、全員の画面をそろえる必要がある機能に使います。関数一覧と上限の正式な情報はチャンネルAPIと上限にあります。
チャンネルを開く
room.plugin.add(チャンネル名) は、その名前のチャンネルオブジェクトを返します。同じ名前でもう一度呼ぶと、同じオブジェクトを返します。同じチャンネル名を使う人どうしでデータをやり取りします。
U.chat('my-room').on('after.create', function (room) {
var dice = room.plugin.add('dice');
});
チャンネル名は英数字で始め、英数字・_・- だけを使った64文字以内にしてください(このルールを守らないと save は拒否されます)。ほかの機能と重ならないよう、自分のサービス名を先頭に付けることをおすすめします。
送信する
データは常に配列で送ります。
dice.send([4]); // チャットルームの全員に(自分を含む)
dice.sendTo('홍길동', ['hello', 1]); // そのニックネームの1人だけに
- 配列の要素に使えるのは文字列・数値・真偽値だけです。オブジェクト・配列・
nullは送信中に取り除かれるため、構造が必要な場合は要素を分けて送るか、文字列にして送ってください。 sendで送ったデータは送信者自身も受け取ります。sendToは受信者だけが受け取ります。隠しミュート中の人が送った場合は、どちらも本人にだけ戻ります。- 無料チャットルームでは、直近60秒間の受信者数の合計に上限があり、超えるとエラー428になります。頻繁に送る機能では送信回数を減らしてください。→ チャンネルAPIと上限
受信する
dice.onReceived(function (room, msg) {
// msg.user 送信者 { nick, id, level, auth, ... }
// msg.type 0 全員に送られたもの、1 自分だけに送られたもの
// msg.data 送られた配列
});
コールバックはほかのイベントと同じく (room, data) を受け取ります。同じデータはイベントの before.plugin、after.plugin でも届きます。
受け取ったデータを検証する
チャンネルのデータは、チャットルームにいる誰でも開発者ツールで好きな値を入れて送れます。受信側では必ず検証してください。
- 要素の数と型、値の範囲を確認し、合わないものは捨てます。
- 画面に表示するときは
textContentを使うか、エスケープします。room.printはHTMLとして解釈します。 - 送信者を確認するときは
msg.user.auth(0ゲスト、1会員、2モデレーター、3管理者、4サーバー)を見ます。ニックネームだけで判断しないでください。 - 結果の公平さが重要な場合(サイコロ、抽選)は、1人が決めた値をそのまま信用せず、サーバーで決めてサーバーAPIから送るようにしてください。→ サーバーからチャットルームに通知を送る
入力コマンドを受け取る
addParser を登録すると、基本スキンの入力欄に !チャンネル名 引数... と入力したときに、その関数が引数の配列を受け取ります。その入力はチャットメッセージとして送信されません。関数が false を返すと処理しなかったものとみなされ、入力は通常のメッセージとして送信されます。
dice.addParser(function (args) {
// 入力: !dice → args: []
dice.send([Math.floor(Math.random() * 6) + 1]);
});
状態を保存する
save(配列) は、チャンネルの最新の状態をサーバーに保存します。あとから入室した人は、入室時に保存された値を受け取ります。clear() は保存した値を削除します。
- 保存できるのはモデレーター以上だけです。
- 保存しても、いまいる人には送信されません。いまいる人にも知らせるには
sendも一緒に呼んでください。 - 入室時に受け取る保存値は
type1(自分だけ)で、送信者はサーバーユーザー(auth4、ニックネームなし)として届きます。誰が保存したかはわかりません。 - 保存サイズには上限があり、無料チャットルームでは別のチャンネルに保存すると、既存のチャンネルの保存値が削除されます。→ チャンネルAPIと上限
// 管理者が選んだ動画IDを保存し、いまいる人にも送る
video.save(['dQw4w9WgXcQ']);
video.send(['dQw4w9WgXcQ']);
閉じる
destroy() はチャンネルを閉じ、登録した受信関数とコマンド関数もあわせて破棄します。同じ名前でもう一度 add すると、新しいチャンネルが開きます。
コード全体
!dice と入力するとサイコロを振り、結果を全員に知らせる例です。
<script>U=window.U=window.U||{},U.events=U.events||[],U.chat=function(n){return{on:function(e,t){U.events.push([n,e,t])},off:function(e){for(var t=U.events.length;t>0;)U.events[--t][0]==n&&U.events[t][1]==e&&U.events.splice(t,1)}}};</script>
<script async src="https://client.uchat.io/uchat.js"></script>
<u-chat room="my-room" style="display:inline-block; width:100%; max-width:500px; height:500px;"></u-chat>
<script>
function escapeHtml(text) {
return String(text).replace(/[&<>"']/g, function (c) {
return { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }[c];
});
}
U.chat('my-room').on('after.create', function (room) {
var dice = room.plugin.add('dice');
dice.onReceived(function (room, msg) {
var value = msg.data[0];
if (msg.data.length !== 1 || typeof value !== 'number') return;
if (value % 1 !== 0 || value < 1 || value > 6) return;
var nick = msg.user ? msg.user.nick : '?';
room.print(escapeHtml(nick) + 'さんのサイコロ: ' + value);
});
dice.addParser(function () {
dice.send([Math.floor(Math.random() * 6) + 1]);
});
});
</script>
一緒に見る機能やゲームのような、より大きな例はYouTubeを一緒に見るとじゃんけんにあります。
読んでもよくわからない場合は お問い合わせ掲示板に質問を書き込んでください。