paint-brush
リアルタイムチャットアプリを構築するために必要なフレームワークはこちら@harishk22
1,016 測定値
1,016 測定値

リアルタイムチャットアプリを構築するために必要なフレームワークはこちら

Harish
Harish HackerNoon profile picture

Harish

@harishk22

I am a full-stack developer, and I make video tutorials...

13 分 read2025/01/21
Read on Terminal Reader
Read this story in a terminal
Print this story
tldt arrow
ja-flagJA
この物語を日本語で読んでください!
en-flagEN
Read this story in the original language, English!
tr-flagTR
Bu hikayeyi Türkçe okuyun!
es-flagES
Lee esta historia en Español!
zh-flagZH
用繁體中文閱讀這個故事!
ln-flagLN
Tanga lisolo oyo na lingala!
xh-flagXH
Funda eli bali ngesiXhosa!
el-flagEL
Διαβάστε αυτή την ιστορία στα ελληνικά!
fa-AF-flagFA-AF
این داستان را به زبان دری بخوانید!
tg-flagTG
Ин қиссаро бо забони тоҷикӣ хонед!
rw-flagRW
Soma iyi nkuru muri Kinyarwanda!
si-flagSI
මේ කතාව සිංහලෙන් කියවන්න!
az-flagAZ
Bu hekayəni Azərbaycan dilində oxuyun!
JA

長すぎる; 読むには

このチュートリアルでは、Laravel、Nuxt 3、Sanctum、Laravel Reverb を使用してリアルタイム チャット アプリケーションを構築します。ユーザー認証を設定し、安全な API に接続し、チャットが即座に更新されてスムーズで応答性の高いエクスペリエンスが実現されるようにします。
featured image - リアルタイムチャットアプリを構築するために必要なフレームワークはこちら
Harish HackerNoon profile picture
Harish

Harish

@harishk22

I am a full-stack developer, and I make video tutorials on my youtube channel, Qirolab.

0-item

STORY’S CREDIBILITY

Code License

Code License

The code in this story is for educational purposes. The readers are solely responsible for whatever they build with it.

このチュートリアルでは、Laravel、Nuxt 3、Sanctum、Laravel Reverb を使用して、ユーザー間の安全でライブなメッセージングを処理するリアルタイム チャット アプリケーションを構築します。ユーザー認証を設定し、安全な API に接続し、チャットが即座に更新されてスムーズで応答性の高いエクスペリエンスが実現されるようにします。


シングルページ アプリケーション (SPA) と API 認証の両方を効率的に処理する SPA 認証を管理するモジュールを使用します。このモジュールの使用の詳細については、 Nuxt 3 SPA 認証に関する記事を参照してください。


このプロジェクトでは、リアルタイム イベント ブロードキャスト用に Laravel Reverb を設定し、Sanctum で認証を実装し、チャット メッセージを動的に表示および管理する Nuxt 3 フロントエンドを構築します。さあ、始めましょう!


前提条件

  • Laravel、Sanctum、Nuxt 3 に関する基本的な知識。
  • Laravel でのイベントブロードキャストの理解。
  • Sanctum でセットアップされた Laravel プロジェクト。
  • Nuxt 3 がインストールされ、アプリのフロントエンドとして構成されます。

ステップ1: Laravel SanctumとLaravel Reverbをセットアップする

まず、Laravel Sanctum がインストールされ、設定されていることを確認します。Sanctum を使用すると、シングルページ アプリケーション (SPA) のトークンベースの認証が可能になります。次に、リアルタイム機能を利用するために Laravel Reverb をインストールして設定します。


次の Reverb 環境変数を.envファイルに追加します。

 REVERB_APP_ID=my-app-id REVERB_APP_KEY=my-app-key REVERB_APP_SECRET=my-app-secret REVERB_HOST="localhost" REVERB_PORT=8080 REVERB_SCHEME=http

ステップ2: チャットメッセージテーブル移行の作成

チャット メッセージを保存するには、 chat_messagesテーブルの移行を作成します。以下を実行します。

 php artisan make:migration create_chat_messages_table


移行ファイルを次のように更新します。

 Schema::create('chat_messages', function (Blueprint $table) { $table->id(); $table->foreignId('receiver_id'); $table->foreignId('sender_id'); $table->text('text'); $table->timestamps(); });


移行を実行してテーブルを作成します。

 php artisan migrate

ステップ3: MessageSentイベントを作成する

メッセージをリアルタイムでブロードキャストするには、 MessageSentイベント クラスを作成します。

 php artisan make:event MessageSent


イベント クラスを更新します。

 <?php namespace App\Events; use App\Models\ChatMessage; use Illuminate\Broadcasting\InteractsWithSockets; use Illuminate\Broadcasting\PrivateChannel; use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow; use Illuminate\Foundation\Events\Dispatchable; use Illuminate\Queue\SerializesModels; class MessageSent implements ShouldBroadcastNow { use Dispatchable, InteractsWithSockets, SerializesModels; public function __construct(public ChatMessage $message) { // } public function broadcastOn(): array { return [new PrivateChannel("chat.{$this->message->receiver_id}")]; } }

ステップ4: ブロードキャストチャンネルを定義する

channels.phpで、ブロードキャスト チャネルを定義します。

 Broadcast::channel('chat.{id}', function ($user, $id) { return (int) $user->id === (int) $id; });

ステップ5: メッセージの取得と送信のルートを定義する

チャット メッセージの送信と取得を管理するには、次のルートを追加します。

 Route::get('/messages/{user}', function (User $user, Request $request) { return ChatMessage::query() ->where(function ($query) use ($user, $request) { $query->where('sender_id', $request->user()->id) ->where('receiver_id', $user->id); }) ->orWhere(function ($query) use ($user, $request) { $query->where('sender_id', $user->id) ->where('receiver_id', $request->user()->id); }) ->with(['sender', 'receiver']) ->orderBy('id', 'asc') ->get(); })->middleware('auth:sanctum'); Route::post('/messages/{user}', function (User $user, Request $request) { $request->validate(['message' => 'required|string']); $message = ChatMessage::create([ 'sender_id' => $request->user()->id, 'receiver_id' => $user->id, 'text' => $request->message ]); broadcast(new MessageSent($message)); return $message; });

ステップ6: Nuxt 3でリバーブを設定する

Nuxt 3 が Reverb に接続できるようにするには、次の変数を.envファイルに追加します。

 NUXT_PUBLIC_REVERB_APP_ID=my-app-id NUXT_PUBLIC_REVERB_APP_KEY=my-app-key NUXT_PUBLIC_REVERB_APP_SECRET=my-app-secret NUXT_PUBLIC_REVERB_HOST="localhost" NUXT_PUBLIC_REVERB_PORT=8080 NUXT_PUBLIC_REVERB_SCHEME=http


次に、 nuxt.config.tsにロードします。

 export default defineNuxtConfig({ runtimeConfig: { public: { REVERB_APP_ID: process.env.NUXT_PUBLIC_REVERB_APP_ID, REVERB_APP_KEY: process.env.NUXT_PUBLIC_REVERB_APP_KEY, REVERB_APP_SECRET: process.env.NUXT_PUBLIC_REVERB_APP_SECRET, REVERB_HOST: process.env.NUXT_PUBLIC_REVERB_HOST, REVERB_PORT: process.env.NUXT_PUBLIC_REVERB_PORT, REVERB_SCHEME: process.env.NUXT_PUBLIC_REVERB_SCHEME, }, }, });

ステップ 7: Nuxt 3 で Laravel Echo クライアントをセットアップする

リアルタイム更新を管理するには、 laravel-echo.client.tsプラグインを作成します。

 import Echo from "laravel-echo"; import Pusher, { type ChannelAuthorizationCallback } from "pusher-js"; declare global { interface Window { Echo: Echo; Pusher: typeof Pusher; } } export default defineNuxtPlugin(() => { window.Pusher = Pusher; const config = useRuntimeConfig(); const echo = new Echo({ broadcaster: "reverb", key: config.public.REVERB_APP_KEY, wsHost: config.public.REVERB_HOST, wsPort: config.public.REVERB_PORT ?? 80, wssPort: config.public.REVERB_PORT ?? 443, forceTLS: (config.public.REVERB_SCHEME ?? "https") === "https", enabledTransports: ["ws", "wss"], authorizer: (channel, options) => ({ authorize: (socketId, callback) => { useSanctumFetch("api/broadcasting/auth", { method: "post", body: { socket_id: socketId, channel_name: channel.name }, }) .then(response => callback(null, response)) .catch(error => callback(error, null)); }, }), }); return { provide: { echo } }; });

ステップ8: Nuxt 3でリアルタイムチャットインターフェースを構築する

Nuxt 3 アプリでリアルタイム チャットを有効にするために、ユーザーが他のユーザーを選択してチャットできる新しいページ、 chats > [id].vueを作成しました。このページは、Laravel バックエンドに接続してチャット メッセージとユーザー データを管理し、リアルタイム更新と入力インジケーターに Laravel Echo と WebSocket を使用します。


このチャット機能の構造の詳細は次のとおりです。

ステップ8.1: 選択したユーザーのチャットデータを読み込む

まず、 useRouteコンポーザブルを使用して URL からuserID取得します。このuserIDチャットしているユーザーを識別し、必要なユーザー メッセージとチャット メッセージを読み込みます。

 const route = useRoute(); const userID = route.params.id; const { user: currentUser } = useSanctum<User>(); const { data: user } = await useAsyncData( `user-${userID}`, () => useSanctumFetch<User>(`/api/users/${userID}`) ); const { data: messages } = useAsyncData( `messages-${userID}`, () => useSanctumFetch<ChatMessage[]>(`/api/messages/${userID}`), { default: (): ChatMessage[] => [] } );

このスニペットは、カスタム コンポーザブルであるuseSanctumFetch使用して、ページがマウントされるときにメッセージを非同期的に読み込みます。

ステップ 8.2: チャット メッセージの表示

各メッセージを動的にレンダリングし、現在のユーザーからのメッセージかチャット参加者からのメッセージかに基づいてスタイルを設定します。

 <div ref="messagesContainer" class="p-4 overflow-y-auto max-h-fit"> <div v-for="message in messages" :key="message.id" class="flex items-center mb-2"> <div v-if="message.sender_id === currentUser.id" class="p-2 ml-auto text-white bg-blue-500 rounded-lg"> {{ message.text }} </div> <div v-else class="p-2 mr-auto bg-gray-200 rounded-lg"> {{ message.text }} </div> </div> </div>

チャット ウィンドウはnextTick()を使用して最新のメッセージまで自動的にスクロールします。

 watch( messages, () => { nextTick(() => messageContainerScrollToBottom()); }, { deep: true } ); function messageContainerScrollToBottom() { if (!messagesContainer.value) return; messagesContainer.value.scrollTo({ top: messagesContainer.value.scrollHeight, behavior: 'smooth' }); }

ステップ 8.3: 新しいメッセージを送信する

ユーザーは入力フィールドを使用してメッセージを送信できます。送信すると、POST リクエストが Laravel バックエンドに送信されます。

 const newMessage = ref(""); const sendMessage = async () => { if (!newMessage.value.trim()) return; const messageResponse = await useSanctumFetch<ChatMessage>(`/api/messages/${userID}`, { method: "post", body: { message: newMessage.value } }); messages.value.push(messageResponse); newMessage.value = ""; };

メッセージは送信後すぐに更新されます。

ステップ 8.4: Laravel Echo を使用したリアルタイム機能

Laravel Echo は、 MessageSenttypingなどの主要なイベントをリッスンします。

 onMounted(() => { if (currentUser.value) { $echo.private(`chat.${currentUser.value.id}`) .listen('MessageSent', (response: { message: ChatMessage }) => { messages.value.push(response.message); }) .listenForWhisper("typing", (response: { userID: number }) => { isUserTyping.value = response.userID === user.value?.id; if (isUserTypingTimer.value) clearTimeout(isUserTypingTimer.value); isUserTypingTimer.value = setTimeout(() => { isUserTyping.value = false; }, 1000); }); } });

これはリアルタイムのメッセージ更新と入力インジケーターを処理します。これらは 1 秒間操作しないと消えます。

ステップ 8.5: 入力インジケーター

入力インジケーターを表示するには、 whisperを使用して「入力」イベントをトリガーします。

 const sendTypingEvent = () => { if (!user.value || !currentUser.value) return; $echo.private(`chat.${user.value.id}`).whisper("typing", { userID: currentUser.value.id }); };

このイベントはユーザーが入力するたびに送信され、受信者には入力インジケーターが表示されます。

ステップ 8.6: ユーザー インターフェイス

チャット インターフェイスには、選択したユーザーの名前を含むヘッダーと、メッセージのセクションと入力フィールドが含まれます。

 <template> <div> <header v-if="user" class="bg-white shadow"> <div class="px-4 py-6 mx-auto max-w-7xl sm:px-6 lg:px-8"> <h1 class="text-2xl font-bold ">{{ user.name }}</h1> </div> </header> <div class="flex flex-col items-center py-5"> <div class="container w-full h-full p-8 space-y-3 bg-white rounded-xl"> <div v-if="currentUser"> <div class="flex flex-col justify-end h-80"> <div ref="messagesContainer" class="p-4 overflow-y-auto max-h-fit"> <div v-for="message in messages" :key="message.id" class="flex items-center mb-2"> <div v-if="message.sender_id === currentUser.id" class="p-2 ml-auto text-white bg-blue-500 rounded-lg"> {{ message.text }} </div> <div v-else class="p-2 mr-auto bg-gray-200 rounded-lg"> {{ message.text }} </div> </div> </div> </div> <div class="flex-shrink-0"> <span v-if="user && isUserTyping" class="text-gray-500"> {{ user.name }} is typing... </span> <div class="flex items-center justify-between w-full p-4 border-t border-gray-200"> <input type="text" v-model="newMessage" @keydown="sendTypingEvent" @keyup.enter="sendMessage" class="w-full p-2 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="Type a message..." /> <button @click.prevent="sendMessage" class="inline-flex items-center justify-center w-12 h-12 ml-4 text-white bg-blue-500 rounded-lg hover:bg-blue-600"> <svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14 5l7 7m0 0l-7 7m7-7H3" /> </svg> </button> </div> </div> </div> </div> </div> </div> </template>

これで、Nuxt 3 で Laravel Sanctum と Echo を使用したリアルタイム チャット機能のセットアップが完了します。

結論

これで、Laravel、Sanctum、Reverb、Nuxt 3 を使用して、安全なリアルタイム チャット アプリケーションが作成されました。このセットアップは、メッセージ反応や複数のチャットルームなどの追加機能を含めるように簡単に拡張できます。


完全なコードについては、 GitHub リポジトリをご覧ください。

L O A D I N G
. . . comments & more!

About Author

Harish HackerNoon profile picture
I am a full-stack developer, and I make video tutorials on my youtube channel, Qirolab.

ラベル

この記事は...

Read on Terminal Reader
Read this story in a terminal
 Terminal
Read this story w/o Javascript
Read this story w/o Javascript
 Lite
X REMOVE AD