paint-brush
Εδώ είναι τα πλαίσια που χρειάζεστε για να δημιουργήσετε μια εφαρμογή συνομιλίας σε πραγματικό χρόνομε@harishk22
947 αναγνώσεις
947 αναγνώσεις

Εδώ είναι τα πλαίσια που χρειάζεστε για να δημιουργήσετε μια εφαρμογή συνομιλίας σε πραγματικό χρόνο

με 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.
  • Ένα έργο Laravel που δημιουργήθηκε με το Sanctum.
  • Το Nuxt 3 είναι εγκατεστημένο και διαμορφωμένο ως το frontend της εφαρμογής σας.

Βήμα 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: Διαμόρφωση του 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 Client στο 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 , ένα προσαρμοσμένο composable, για τη ασύγχρονη φόρτωση μηνυμάτων κατά την προσάρτηση της σελίδας.

Βήμα 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 αποστέλλεται στο backend της 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 .