paint-brush
Tala ba Cadres Osengeli Pona Kotonga App Ya Chat En Temps Réelpene@harishk22
947 botángi
947 botángi

Tala ba Cadres Osengeli Pona Kotonga App Ya Chat En Temps Réel

pene Harish13m2025/01/21
Read on Terminal Reader

Molai mingi; Mpo na kotánga

Na mateya oyo, tokotonga application ya chat en temps réel en utilisant Laravel, Nuxt 3, Sanctum, na Laravel Reverb. Tokobongisa bondimi ya mosaleli, toko connecter na API ya securité, mpe tokosala que chat e mise à jour mbala moko mpo na expérience ya malamu mpe ya koyanola.
featured image - Tala ba Cadres Osengeli Pona Kotonga App Ya Chat En Temps Réel
Harish HackerNoon profile picture
0-item

Na mateya oyo, tokotonga application ya chat en temps réel na kosalelaka Laravel, Nuxt 3, Sanctum, na Laravel Reverb pona ko gérer ba messages ya sécurité pe en direct entre ba usagers. Tokobongisa bondimi ya mosaleli, toko connecter na API ya securité, mpe tokosala que chat e mise à jour mbala moko mpo na expérience ya malamu mpe ya koyanola.


Tokosalela module mpo na ko gérer authentification ya SPA, oyo esimbaka malamu ezala Single-Page Application (SPA) mpe authentification ya API. Mpo na koyeba makambo mingi na ntina ya kosalela module oyo, tala lisolo na ntina ya bondimi ya Nuxt 3 SPA .


Na projet oyo, toko configurer Laravel Reverb pona diffusion ya événement en temps réel, toko mettre en œuvre authentification na Sanctum, pe totonga frontend ya Nuxt 3 oyo elakisaka dynamiquement pe e gérer ba messages ya chat. Tobanda!

Makambo oyo esengeli liboso

  • Koyeba malamu Laravel, Sanctum, mpe Nuxt 3.
  • Compréhension ya émission ya événement na Laravel.
  • Projet moko ya Laravel oyo esalemaki na Sanctum.
  • Nuxt 3 ezali installé mpe configuré lokola frontend ya app na yo.

Etape 1: Kobongisa Laravel Sanctum mpe Laravel Reverb

Ya liboso, sala que Laravel Sanctum ezala installé pe configuré. Sanctum epesaka nzela na bondimi oyo esalemi na bilembo mpo na ba application ya lokasa moko (SPA). Na sima, installer pe configurer Laravel Reverb pona ba capacités en temps réel.


Bakisa ba variables ya environnement Reverb oyo elandi na fichier .env na yo:

 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

Etape 2: Kosala Migration ya Tableau ya ba messages ya chat

Mpo na kobomba ba messages ya chat, sala migration mpo na tableau ya chat_messages . Kopota mbango:

 php artisan make:migration create_chat_messages_table


Mikolo oyo fichier ya migration ndenge elandi:

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


Tambwisa migration mpo na kosala tableau:

 php artisan migrate

Etape 3: Salá Evenement ya MessageSent

Mpo na kotinda ba messages na tango ya solo, sala classe ya événement MessageSent :

 php artisan make:event MessageSent


Mikolo oyo kelasi ya likambo:

 <?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}")]; } }

Etape 4: Limbola ba chaînes ya émission

Na channels.php , limbolá chaîne ya émission:

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

Etape 5: Limbola banzela mpo na kozwa mpe kotinda bansango

Bakisa ba routes oyo pona ko gérer kotinda pe kozua ba messages ya chat:

 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; });

Etape 6: Configurer Reverb na Nuxt 3

Pona ko permettre Nuxt 3 e connecter na Reverb, bakisa ba variables oyo na fichier .env na yo:

 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


Na sima, charger bango na 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, }, }, });

Etape 7: Kobongisa Client ya Laravel Echo na Nuxt 3

Mpo na kotambwisa ba mises à jour na tango ya solo, sala plugin 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 } }; });

Etape 8: Tongela Interface ya kosolola na tango ya solo na Nuxt 3

Mpo na kofungola kosolola na ntango ya solosolo na programɛ na biso ya Nuxt 3, nasalaki lokasa ya sika, chats > [id].vue , epai basaleli bakoki kopona mpe kosolola na basaleli mosusu. Lokasa oyo ezo connecter na backend ya Laravel pona ko gérer ba messages ya chat na ba données ya usager, kosalela Laravel Echo na WebSockets pona ba mises à jour ya temps réel pe ba indicateurs ya type.


Tala bopanzani ya ndenge to structurer fonctionnalité ya chat oyo:

Etape 8.1: Kokɔtisa ba données ya chat ya mosaleli oyo oponi

Ya liboso, tozuaka userID na URL na useRoute composable. userID oyo emonisaka mosaleli oyo tozali kosolola na ye mpe ekɔtisaka bansango ya mosaleli mpe ya kosolola oyo esengeli.

 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[] => [] } );

Eteni oyo esaleli useSanctumFetch , composable personnalisé, mpo na ko charger ba messages asynchrone tango lokasa emata.

Etape 8.2: Kolakisa ba messages ya chat

Tozali kopesa nsango mokomoko na ndenge ya dynamique, kosala yango na kolanda soki euti na mosaleli ya lelo to moto oyo azali kosangana na lisolo.

 <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>

Fenêtre ya chat ezo défiler automatiquement na message ya sika na nzela ya nextTick() .

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

Etape 8.3: Kotinda ba messages ya sika

Ba usagers bakoki kotinda ba messages na champ ya entrée. Na tango ya kotinda, bosengi ya POST etindamaka na backend ya 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 = ""; };

Ba messages ezo mise à jour mbala moko sima ya kotinda yango.

Etape 8.4: Makambo ya tango ya solo na Laravel Echo

Laravel Echo eyokaka makambo ya ntina lokola MessageSent mpe typing .

 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); }); } });

Yango esimbaka ba mises à jour ya ba messages na tango ya solo mpe ba indicateurs ya kokoma, oyo elimwaka sima ya segɔnde moko ya inactivité.

Etape 8.5: Indicateur ya kokoma

Mpo na kolakisa elembo ya kokoma, tobandisaka likambo ya "kokoma" na whisper .

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

Likambo oyo etindamaka ntango nyonso oyo mosaleli akokoma, mpe mozwi amonaka elembo ya kokoma.

Etape 8.6: Interface ya mosaleli

Interface ya kosolola ezali na motó ya likambo oyo ezali na nkombo ya mosaleli oyo oponi mpe biteni mpo na bansango mpe esika ya kokɔtisa.

 <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>

Yango esilisaka bobongisi ya makambo ya kosolola na ntango ya solosolo na kosaleláká Laravel Sanctum mpe Echo na Nuxt 3.

Maloba ya nsuka

Tosali sikoyo application ya chat ya sécurité, en temps réel en utilisant Laravel, Sanctum, Reverb, na Nuxt 3. Setup oyo ekoki kozala facilement échelle pona ko inclure ba fonctionnalités ya kobakisa lokola ba réactions ya message to ba salles de chat ebele.


Mpo na code mobimba, kota na ebombelo ya 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.

KOKANGA BA ÉTIQUES

ARTICLE OYO EZALAKI PRESENTE NA...