Skip to main content

WebSocket接続について

Rheel Chat APIは、Socket.IOを使用したリアルタイム双方向通信をサポートしています。 これにより、メッセージの即時受信や各種イベント通知をリアルタイムで実現できます。

接続エンドポイント

wss://<application_id>.chat.rheel.net/v1/ws

認証

WebSocket接続には、セッショントークンによる認証が必要です。

接続パラメータ

パラメータ必須説明
tokenYesセッショントークン発行APIで取得したセッショントークン

接続の実装

import { io } from 'socket.io-client';

const socket = io('wss://<application_id>.chat.rheel.net', {
  path: '/v1/ws',
  auth: {
    token: '<SESSION_TOKEN>'
  },
  transports: ['websocket', 'polling'],
  reconnection: true
});

// 接続成功
socket.on('connect', () => {
  console.log('Connected to Rheel Chat');
  console.log('Socket ID:', socket.id);
});

// 接続エラー
socket.on('connect_error', (error) => {
  console.error('Connection error:', error.message);

  if (error.message.includes('authentication') || error.message.includes('unauthorized')) {
    console.error('認証エラー: トークンが無効または期限切れです');
  }
});

// 切断
socket.on('disconnect', (reason) => {
  console.log('Disconnected:', reason);
});

// エラーハンドリング
socket.on('error', (error) => {
  console.error('Socket error:', error);
});

チャンネルへの自動参加

WebSocket接続が確立されると、ユーザーが所属している全チャンネルに自動的に参加します。
// 接続成功
socket.on('connect', () => {
  console.log('Connected to Rheel Chat');
  console.log('Socket ID:', socket.id);
  // この時点で、所属している全チャンネルに自動参加済み
});
接続後、ユーザーが所属している全チャンネルのメッセージやイベントをリアルタイムで受信できます。

イベントの受信

WebSocket接続を通じて、以下のイベントをリアルタイムで受信できます。

メッセージイベント

// 新規メッセージ作成
socket.on('messages:created', (data) => {
  console.log('メッセージが作成されました:', data);
  // data = {
  //   id: "msg_123",
  //   channel_id: "ch_456",
  //   user_id: "user_789",
  //   text: "こんにちは",
  //   created_at: "2025-03-21T10:00:00Z",
  //   ...
  // }
});

// メッセージ更新
socket.on('messages:updated', (data) => {
  console.log('メッセージが更新されました:', data);
});

// メッセージ削除
socket.on('messages:deleted', (data) => {
  console.log('メッセージが削除されました:', data);
  // data = {
  //   message_id: "msg_123",
  //   channel_id: "ch_456",
  //   ...
  // }
});

リアクションイベント

// リアクション追加
socket.on('reactions:added', (data) => {
  console.log('リアクションが追加されました:', data);
  // data = {
  //   message_id: "msg_123",
  //   user_id: "user_789",
  //   emoji: "👍",
  //   ...
  // }
});

// リアクション削除
socket.on('reactions:removed', (data) => {
  console.log('リアクションが削除されました:', data);
});

既読イベント

// 既読状態更新
socket.on('readReceipts:updated', (data) => {
  console.log('既読状態が更新されました:', data);
  // data = {
  //   channel_id: "ch_456",
  //   user_id: "user_789",
  //   message_id: "msg_123",
  //   read_at: "2025-03-21T10:00:00Z",
  //   ...
  // }
});

添付ファイルイベント

// 添付ファイル削除
socket.on('attachments:deleted', (data) => {
  console.log('添付ファイルが削除されました:', data);
  // data = {
  //   attachment_id: "att_123",
  //   message_id: "msg_456",
  //   ...
  // }
});

実装例

以下は、チャンネルに参加してメッセージを送受信する完全な実装例です。
import { io } from 'socket.io-client';

// 接続
const socket = io('wss://<application_id>.chat.rheel.net', {
  path: '/v1/ws',
  auth: {
    token: '<SESSION_TOKEN>'
  },
  transports: ['websocket', 'polling'],
  reconnection: true,
  reconnectionAttempts: 5,
  reconnectionDelay: 1000
});

socket.on('connect', () => {
  console.log('接続成功:', socket.id);
  // 所属している全チャンネルに自動参加済み
});

// メッセージ受信
socket.on('messages:created', (message) => {
  console.log('新規メッセージ:', message.text);
  displayMessage(message);
});

socket.on('messages:updated', (message) => {
  console.log('メッセージ更新:', message);
  updateMessage(message);
});

socket.on('messages:deleted', (data) => {
  console.log('メッセージ削除:', data.message_id);
  removeMessage(data.message_id);
});

// リアクション受信
socket.on('reactions:added', (data) => {
  console.log('リアクション追加:', data);
  addReaction(data);
});

socket.on('reactions:removed', (data) => {
  console.log('リアクション削除:', data);
  removeReaction(data);
});

// 既読受信
socket.on('readReceipts:updated', (data) => {
  console.log('既読更新:', data);
  updateReadReceipt(data);
});

// エラーハンドリング
socket.on('connect_error', (error) => {
  console.error('接続エラー:', error.message);
});

socket.on('error', (error) => {
  console.error('エラー:', error);
});

socket.on('disconnect', (reason) => {
  console.log('切断:', reason);
});

// ヘルパー関数(実装例)
function displayMessage(message) {
  // UIにメッセージを表示
}

function updateMessage(message) {
  // UIのメッセージを更新
}

function removeMessage(messageId) {
  // UIからメッセージを削除
}

function addReaction(data) {
  // UIにリアクションを追加
}

function removeReaction(data) {
  // UIからリアクションを削除
}

function updateReadReceipt(data) {
  // UIの既読状態を更新
}

再接続戦略

Socket.IOはデフォルトで自動再接続をサポートしています。
const socket = io('wss://<application_id>.chat.rheel.net', {
  path: '/v1/ws',
  auth: {
    token: '<SESSION_TOKEN>'
  },
  transports: ['websocket', 'polling'],
  // 再接続設定
  reconnection: true,
  reconnectionAttempts: 5,
  reconnectionDelay: 1000,
  reconnectionDelayMax: 5000,
  timeout: 20000
});

// 再接続試行
socket.io.on('reconnect_attempt', (attemptNumber) => {
  console.log(`再接続試行: ${attemptNumber}回目`);
});

// 再接続成功
socket.io.on('reconnect', (attemptNumber) => {
  console.log(`再接続成功: ${attemptNumber}回目の試行後`);
  // 再接続後、自動的に全チャンネルに再参加されます
});

// 再接続失敗
socket.io.on('reconnect_failed', () => {
  console.error('再接続に失敗しました');
});

ベストプラクティス

  • アプリケーション起動時に接続を確立
  • バックグラウンド移行時は切断を検討
  • フォアグラウンド復帰時に再接続
  • 再接続後は自動的に全チャンネルに再参加されます
  • イベントリスナーは適切にクリーンアップ
  • コンポーネント破棄時にリスナーを削除
  • 大量のメッセージ履歴は適切にページング
  • 不要になったらsocket.disconnect()を呼ぶ
  • すべてのイベントでエラーハンドリングを実装
  • トークン期限切れに対応
  • ネットワークエラーを適切に処理
  • connect_errorerrorイベントを監視
  • 不要なイベントリスナーは登録しない
  • メッセージ受信時のUI更新を最適化
  • 大量のイベント受信時はバッチ処理を検討

トラブルシューティング

症状: connect_errorイベントが発生する確認事項:
  • トークンが正しく設定されているか
  • トークンの有効期限が切れていないか
  • エンドポイントURLが正しいか
  • ネットワーク接続が正常か
症状: messages:createdイベントが発火しない確認事項:
  • WebSocket接続が正常に確立されているか(connectイベントを受信したか)
  • ユーザーがチャンネルに所属しているか(REST APIで確認)
  • 正しいチャンネルでメッセージが送信されているか
症状: 接続が不安定対策:
  • transportsの順序を調整(['websocket', 'polling']
  • タイムアウト値を調整
  • ネットワーク環境を確認

次のステップ