paint-brush
Инҳо чаҳорчӯбаҳое ҳастанд, ки ба шумо лозим аст, ки як барномаи воқеии чат созедаз ҷониби@harishk22
951 хониш
951 хониш

Инҳо чаҳорчӯбаҳое ҳастанд, ки ба шумо лозим аст, ки як барномаи воқеии чат созед

аз ҷониби Harish13m2025/01/21
Read on Terminal Reader

Хеле дароз; Хондан

Дар ин дастур, мо бо истифода аз Laravel, Nuxt 3, Sanctum ва Laravel Reverb замимаи чатро дар вақти воқеӣ месозем. Мо аутентификатсияи корбарро насб мекунем, ба API-и бехатар пайваст мешавем ва кафолат медиҳем, ки чат барои таҷрибаи ҳамвор ва ҷавобгӯ фавран нав мешавад.
featured image - Инҳо чаҳорчӯбаҳое ҳастанд, ки ба шумо лозим аст, ки як барномаи воқеии чат созед
Harish HackerNoon profile picture
0-item

Дар ин дастур, мо бо истифода аз Laravel, Nuxt 3, Sanctum ва Laravel Reverb як барномаи воқеии сӯҳбатро барои коркарди паёмнависии бехатар ва зинда байни корбарон месозем. Мо аутентификатсияи корбарро насб мекунем, ба API-и бехатар пайваст мешавем ва кафолат медиҳем, ки чат барои таҷрибаи ҳамвор ва ҷавобгӯ фавран нав мешавад.


Мо модулро барои идоракунии аутентификатсияи SPA истифода хоҳем кард, ки он ҳам аризаи ягонаи саҳифа (SPA) ва ҳам аутентификатсияи API-ро самаранок идора мекунад. Барои гирифтани маълумоти бештар дар бораи истифодаи ин модул, ба мақола дар бораи аутентификатсияи Nuxt 3 SPA нигаред.


Дар ин лоиҳа, мо Laravel Reverb-ро барои пахши воқеии рӯйдодҳо танзим мекунем, аутентификатсияро бо Sanctum амалӣ месозем ва фронти Nuxt 3-ро месозем, ки паёмҳои чатро ба таври динамикӣ намоиш ва идора мекунад. Биёед оғоз кунем!

Шартҳои пешакӣ

  • Шиносоии асосӣ бо Laravel, Sanctum ва Nuxt 3.
  • Фаҳмидани пахши рӯйдодҳо дар Ларавел.
  • Лоиҳаи Laravel бо Sanctum таъсис дода шудааст.
  • Nuxt 3 ҳамчун интерфейси барномаи шумо насб ва танзим карда шудааст.

Қадами 1: Насб кардани Laravel Sanctum ва Laravel Reverb

Аввалан, боварӣ ҳосил кунед, ки Laravel Sanctum насб ва танзим карда шудааст. Sanctum имкон медиҳад, ки аутентификатсия дар асоси нишонаҳо барои замимаҳои як саҳифа (SPA). Сипас, Laravel Reverb-ро барои қобилиятҳои вақти воқеӣ насб ва танзим кунед.


Ба файли .env и худ тағирёбандаҳои муҳити Reverb-и зеринро илова кунед:

 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: Танзими Reverb дар 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: Муштарии Laravel Echo дар Nuxt 3 насб кунед

Барои идоракунии навсозиҳои вақти воқеӣ, плагини 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 ва WebSockets барои навсозӣ ва чопкунии нишондиҳандаҳои вақти воқеӣ.


Ин аст шарҳи он, ки мо ин функсияи чатро чӣ гуна сохтор кардаем:

Қадами 8.1: Маълумоти чати корбари интихобшударо бор кунед

Аввалан, мо userID аз URL бо useRoute composable мегирем. Ин 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 рӯйдодҳои калидӣ ба монанди MessageSent ва 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); }); } });

Ин навсозии паёмҳо ва нишондиҳандаҳои чопкуниро дар вақти воқеӣ идора мекунад, ки пас аз як сонияи ғайрифаъолӣ нопадид мешаванд.

Қадами 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>

Ин танзимоти хусусияти сӯҳбатро дар вақти воқеӣ бо истифода аз Laravel Sanctum ва Echo бо Nuxt 3 анҷом медиҳад.

Хулоса

Мо ҳоло бо истифода аз 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.

ТЕГИ овезон кунед

ИН МАКОЛА ДАР...