paint-brush
Hano haribikorwa ukeneye kubaka Porogaramu nyayo-Ikiganirona@harishk22
947 gusoma
947 gusoma

Hano haribikorwa ukeneye kubaka Porogaramu nyayo-Ikiganiro

na Harish13m2025/01/21
Read on Terminal Reader

Birebire cyane; Gusoma

Muriyi nyigisho, tuzubaka porogaramu nyayo yo kuganira dukoresheje Laravel, Nuxt 3, Sanctum, na Laravel Reverb. Tuzashyiraho umukoresha wemeza, duhuze na API itekanye, kandi tumenye neza ko ivugurura ryibiganiro ako kanya kuburambe bworoshye kandi bwitondewe.
featured image - Hano haribikorwa ukeneye kubaka Porogaramu nyayo-Ikiganiro
Harish HackerNoon profile picture
0-item

Muriyi nyigisho, tuzubaka porogaramu nyayo yo kuganira dukoresheje Laravel, Nuxt 3, Sanctum, na Laravel Reverb kugirango dukemure ubutumwa bwizewe kandi bwuzuye hagati yabakoresha. Tuzashyiraho umukoresha wemeza, duhuze na API itekanye, kandi tumenye neza ko ivugurura ryibiganiro ako kanya kuburambe bworoshye kandi bwitondewe.


Tuzakoresha module yo gucunga SPA kwemeza, ikora neza byombi Urupapuro rumwe rukoreshwa (SPA) hamwe no kwemeza API. Kugira ngo umenye byinshi kubyerekeye gukoresha iyi module, reba ingingo kuri Nuxt 3 SPA yo kwemeza .


Muri uyu mushinga, tuzashyiraho Laravel Reverb mugihe nyacyo cyo gutangaza amakuru, dushyire mubikorwa kwemeza hamwe na Sanctum, kandi twubake imbere ya Nuxt 3 yerekana kandi ikayobora ubutumwa bwibiganiro. Reka dutangire!

Ibisabwa

  • Kumenyera shingiro na Laravel, Sanctum, na Nuxt 3.
  • Gusobanukirwa ibyatangajwe muri Laravel.
  • Umushinga wa Laravel washyizweho na Sanctum.
  • Nuxt 3 yashizwemo kandi igizwe nkimbere ya porogaramu yawe.

Intambwe ya 1: Shiraho Laravel Sanctum na Laravel Reverb

Ubwa mbere, menya neza ko Laravel Sanctum yashyizweho kandi igashyirwaho. Sanctum yemerera ibimenyetso-byemewe kwemeza urupapuro rumwe rukoreshwa (SPA). Noneho, shyiramo kandi ugene Laravel Reverb kubushobozi-bwigihe.


Ongeraho ibikurikira Reverb ibidukikije bihinduka muri dosiye yawe .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

Intambwe ya 2: Kora Ubutumwa bwo Kuganira Imbonerahamwe Kwimuka

Kubika ubutumwa bwibiganiro, kora iyimuka kumeza chat_messages . Kwiruka:

 php artisan make:migration create_chat_messages_table


Kuvugurura dosiye yimuka kuburyo bukurikira:

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


Koresha kwimuka kugirango ukore imbonerahamwe:

 php artisan migrate

Intambwe ya 3: Kurema Ubutumwa bwoherejwe

Kugirango utangaze ubutumwa mugihe nyacyo, kora MessageSent bwibikorwa byicyiciro:

 php artisan make:event MessageSent


Kuvugurura ibyiciro byibyiciro:

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

Intambwe ya 4: Sobanura Imiyoboro Yamamaza

channels.php , sobanura umuyoboro wogutangaza:

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

Intambwe ya 5: Sobanura inzira zo Kubona no Kohereza Ubutumwa

Ongeraho izi nzira zo gucunga kohereza no kugarura ubutumwa bwibiganiro:

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

Intambwe ya 6: Hindura Reverb muri Nuxt 3

Kwemerera Nuxt 3 guhuza na Reverb, ongeraho ibi bihinduka muri dosiye yawe .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


Noneho, ubishyire muri 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, }, }, });

Intambwe 7: Shiraho umukiriya wa Laravel Echo muri Nuxt 3

Gucunga amakuru yigihe-gihe, kora laravel-echo.client.ts plugin:

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

Intambwe ya 8: Kubaka Imigaragarire nyayo-Ibiganiro muri Nuxt 3

Kugirango ushoboze kuganira mugihe nyacyo muri porogaramu yacu ya Nuxt 3, nashizeho page nshya, chats > [id].vue , aho abakoresha bashobora guhitamo no kuganira nabandi bakoresha. Uru rupapuro ruhuza inyuma ya Laravel kugirango ucunge ubutumwa bwibiganiro hamwe namakuru yumukoresha, ukoresheje Laravel Echo na WebSockets mugihe nyacyo cyo kuvugurura no kwerekana ibimenyetso.


Dore ibice byuburyo twateguye iyi mikorere yo kuganira:

Intambwe 8.1: Fungura amakuru Yatoranijwe Yabakoresha

Ubwa mbere, dukura userID muri URL hamwe no useRoute ihimbye. Uyu userID yerekana umukoresha tuganira kandi yikoreza umukoresha n'ubutumwa bwo kuganira.

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

Aka gatabo gakoresha useSanctumFetch , yihariye igizwe, kugirango yikoreze ubutumwa butajegajega iyo page ihagaze.

Intambwe 8.2: Kwerekana Ubutumwa bwo Kuganira

Dutanga buri butumwa muburyo bukomeye, tukabushushanya dukurikije niba bituruka kubakoresha ubu cyangwa abitabiriye ibiganiro.

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

Idirishya ryibiganiro rihita ryerekeza kubutumwa buheruka ukoresheje nextTick() .

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

Intambwe 8.3: Kohereza Ubutumwa bushya

Abakoresha barashobora kohereza ubutumwa hamwe numwanya winjiza. Mugihe cyoherejwe, icyifuzo cya POST cyoherejwe inyuma 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 = ""; };

Ubutumwa buravugururwa ako kanya nyuma yo koherezwa.

Intambwe 8.4: Ibihe-Ibiranga na Laravel Echo

Laravel Echo yumva ibintu byingenzi nka MessageSent no 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); }); } });

Ibi bikora ubutumwa bwigihe-gihe cyo kuvugurura no kwandika ibipimo, bikabura nyuma yisegonda yo kudakora.

Intambwe 8.5: Ikimenyetso cyo Kwandika

Kugirango twerekane icyerekezo cyo kwandika, dukurura "kwandika" ibyabaye whisper .

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

Ibirori byoherejwe igihe cyose umukoresha yanditse, kandi uyahawe abona icyerekezo cyo kwandika.

Intambwe 8.6: Imigaragarire y'abakoresha

Isohora ryibiganiro ririmo umutwe hamwe nizina ryatoranijwe ryumukoresha nibice byubutumwa hamwe numwanya winjiza.

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

Ibi birangiza igihe nyacyo cyo kuganira ukoresheje Laravel Sanctum na Echo hamwe na Nuxt 3.

Umwanzuro

Ubu twashizeho porogaramu itekanye, mugihe nyacyo cyo kuganira dukoresheje Laravel, Sanctum, Reverb, na Nuxt 3. Iyi mikorere irashobora kugabanywa byoroshye kugirango ushiremo ibintu byongeweho nkibisubizo byubutumwa cyangwa ibyumba byinshi byo kuganiriramo.


Kode yuzuye, sura ububiko bwa 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.

HANG TAGS

IYI ngingo YATANZWE MU...