paint-brush
Gerçek Zamanlı Sohbet Uygulaması Oluşturmak İçin İhtiyacınız Olan Çerçeveler İşte Bunlarile@harishk22
947 okumalar
947 okumalar

Gerçek Zamanlı Sohbet Uygulaması Oluşturmak İçin İhtiyacınız Olan Çerçeveler İşte Bunlar

ile Harish13m2025/01/21
Read on Terminal Reader

Çok uzun; Okumak

Bu eğitimde, Laravel, Nuxt 3, Sanctum ve Laravel Reverb kullanarak gerçek zamanlı bir sohbet uygulaması oluşturacağız. Kullanıcı kimlik doğrulamasını kuracağız, güvenli bir API'ye bağlanacağız ve sorunsuz ve duyarlı bir deneyim için sohbetin anında güncellenmesini sağlayacağız.
featured image - Gerçek Zamanlı Sohbet Uygulaması Oluşturmak İçin İhtiyacınız Olan Çerçeveler İşte Bunlar
Harish HackerNoon profile picture
0-item

Bu eğitimde, kullanıcılar arasında güvenli ve canlı mesajlaşmayı yönetmek için Laravel, Nuxt 3, Sanctum ve Laravel Reverb kullanarak gerçek zamanlı bir sohbet uygulaması oluşturacağız. Kullanıcı kimlik doğrulamasını kuracağız, güvenli bir API'ye bağlanacağız ve sorunsuz ve duyarlı bir deneyim için sohbetin anında güncellenmesini sağlayacağız.


Modülü, hem Tek Sayfalık Uygulama (SPA) hem de API kimlik doğrulamasını verimli bir şekilde işleyen SPA kimlik doğrulamasını yönetmek için kullanacağız. Bu modülü kullanma hakkında daha fazla bilgi edinmek için Nuxt 3 SPA kimlik doğrulaması makalesine bakın.


Bu projede, Laravel Reverb'i gerçek zamanlı etkinlik yayını için yapılandıracağız, Sanctum ile kimlik doğrulamayı uygulayacağız ve sohbet mesajlarını dinamik olarak görüntüleyen ve yöneten bir Nuxt 3 ön ucu oluşturacağız. Başlayalım!

Ön koşullar

  • Laravel, Sanctum ve Nuxt 3 ile ilgili temel bilgilere sahip olmak.
  • Laravel'de etkinlik yayınlamanın anlaşılması.
  • Sanctum ile kurulmuş bir Laravel projesi.
  • Nuxt 3, uygulamanızın ön yüzü olarak kuruldu ve yapılandırıldı.

Adım 1: Laravel Sanctum ve Laravel Reverb'i Ayarlayın

Öncelikle, Laravel Sanctum'un kurulu ve yapılandırılmış olduğundan emin olun. Sanctum, tek sayfalık uygulamalar (SPA) için belirteç tabanlı kimlik doğrulamaya izin verir. Ardından, Laravel Reverb'i gerçek zamanlı yetenekler için kurun ve yapılandırın.


Aşağıdaki Reverb ortam değişkenlerini .env dosyanıza ekleyin:

 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

Adım 2: Sohbet Mesajları Tablosu Göçünü Oluşturun

Sohbet mesajlarını depolamak için chat_messages tablosu için bir geçiş oluşturun. Çalıştırın:

 php artisan make:migration create_chat_messages_table


Göç dosyasını aşağıdaki şekilde güncelleyin:

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


Tabloyu oluşturmak için geçişi çalıştırın:

 php artisan migrate

Adım 3: MessageSent Olayını Oluşturun

Gerçek zamanlı mesaj yayınlamak için bir MessageSent olay sınıfı oluşturun:

 php artisan make:event MessageSent


Olay sınıfını güncelle:

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

Adım 4: Yayın Kanallarını Tanımlayın

channels.php dosyasında yayın kanalını tanımlayın:

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

Adım 5: Mesajları Getirmek ve Göndermek için Rotaları Tanımlayın

Sohbet mesajlarının gönderilmesini ve alınmasını yönetmek için şu rotaları ekleyin:

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

Adım 6: Nuxt 3'te Reverb'i yapılandırın

Nuxt 3'ün Reverb ile bağlantı kurmasını sağlamak için .env dosyanıza şu değişkenleri ekleyin:

 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


Daha sonra bunları nuxt.config.ts yükleyin:

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

Adım 7: Nuxt 3'te Laravel Echo İstemcisini Kurun

Gerçek zamanlı güncellemeleri yönetmek için laravel-echo.client.ts eklentisini oluşturun:

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

Adım 8: Nuxt 3'te Gerçek Zamanlı Sohbet Arayüzünü Oluşturun

Nuxt 3 uygulamamızda gerçek zamanlı sohbeti etkinleştirmek için kullanıcıların diğer kullanıcıları seçip sohbet edebileceği yeni bir sayfa, chats > [id].vue oluşturdum. Bu sayfa, gerçek zamanlı güncellemeler ve yazım göstergeleri için Laravel Echo ve WebSockets kullanarak sohbet mesajlarını ve kullanıcı verilerini yönetmek için bir Laravel arka ucuna bağlanır.


Bu sohbet işlevselliğini nasıl yapılandırdığımıza dair bir döküm şöyle:

Adım 8.1: Seçili Kullanıcının Sohbet Verilerini Yükle

İlk olarak, useRoute bileşeniyle URL'den userID alırız. Bu userID sohbet ettiğimiz kullanıcıyı tanımlar ve gerekli kullanıcı ve sohbet mesajlarını yükler.

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

Bu kod parçacığı, sayfa bağlandığında mesajları eşzamansız olarak yüklemek için özel bir bileşen olan useSanctumFetch kullanır.

Adım 8.2: Sohbet Mesajlarını Görüntüleme

Her mesajı dinamik olarak oluşturuyoruz ve mevcut kullanıcıdan mı yoksa sohbet katılımcısından mı geldiğine göre biçimlendiriyoruz.

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

Sohbet penceresi nextTick() kullanılarak otomatik olarak en son mesaja kaydırılır.

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

Adım 8.3: Yeni Mesajların Gönderilmesi

Kullanıcılar bir girdi alanıyla mesaj gönderebilirler. Gönderim üzerine, Laravel arka ucuna bir POST isteği gönderilir.

 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 = ""; };

Mesajlar gönderildikten hemen sonra güncellenir.

Adım 8.4: Laravel Echo ile Gerçek Zamanlı Özellikler

Laravel Echo MessageSent ve typing gibi önemli olayları dinler.

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

Bu, bir saniyelik hareketsizlikten sonra kaybolan gerçek zamanlı mesaj güncellemelerini ve yazma göstergelerini yönetir.

Adım 8.5: Yazma Göstergesi

Bir yazma göstergesi göstermek için, whisper ile bir "yazma" olayını tetikleriz.

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

Bu olay, kullanıcı her yazı yazdığında gönderilir ve alıcı yazma göstergesini görür.

Adım 8.6: Kullanıcı Arayüzü

Sohbet arayüzünde, seçilen kullanıcının adının yer aldığı bir başlık ve mesajlar ile giriş alanı için bölümler yer alır.

 <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 ve Echo with Nuxt 3 kullanılarak gerçek zamanlı sohbet özelliği kurulumu tamamlandı.

Çözüm

Artık Laravel, Sanctum, Reverb ve Nuxt 3 kullanarak güvenli, gerçek zamanlı bir sohbet uygulaması oluşturduk. Bu kurulum, mesaj tepkileri veya birden fazla sohbet odası gibi ek özellikleri içerecek şekilde kolayca ölçeklenebilir.


Kodun tamamı için GitHub deposunu ziyaret edin.