リアルタイムデータの送受信

チャンネル(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 も一緒に呼んでください。
  • 入室時に受け取る保存値は type 1(自分だけ)で、送信者はサーバーユーザー(auth 4、ニックネームなし)として届きます。誰が保存したかはわかりません。
  • 保存サイズには上限があり、無料チャットルームでは別のチャンネルに保存すると、既存のチャンネルの保存値が削除されます。→ チャンネル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 { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[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を一緒に見るとじゃんけんにあります。

読んでもよくわからない場合は お問い合わせ掲示板に質問を書き込んでください。

商号 UCHAT · 代表者 김경욱 · 事業者登録番号 141-05-32832
所在地 경기도 파주시 와석순환로 61 · 通信販売業届出番号 2013-경기파주-4485호
代表電話 010-8677-8633 · メール support@uchat.io

ⓒ 2013–2026 UCHAT. All rights reserved.