In today's digital age, users crave real-time interaction. Whether it's for a customer support channel, a collaborative platform, or a social networking app, real-time chat functionality can significantly enhance the user experience. Laravel, the popular PHP framework known for its elegant syntax and robust features, offers a powerful tool for building such features: Laravel Reverb.
This article will guide you through creating a real-time chat system using Laravel Reverb and Vue.js 3. We'll cover setting up Laravel Reverb, building the backend logic with Laravel, and implementing the frontend with Vue.js.
What is Laravel Reverb?
Laravel Reverb is a first-party WebSocket server specifically designed for Laravel applications. It facilitates seamless, two-way communication between your server and client, allowing for instant data updates without requiring constant page refreshes.
Why Choose Laravel Reverb for Real-Time Chat?
- Seamless Integration: As an official Laravel package, Reverb integrates effortlessly with the Laravel ecosystem.
- Performance: Built for speed and scalability, Reverb can handle a high volume of concurrent users and messages.
- Security: Reverb leverages Laravel's built-in security mechanisms for secure communication.
Let's Get Started!
1. Project Setup
Make sure you have a fresh Laravel installation. If not, create one:
composer create-project laravel/laravel your-chat-app
cd your-chat-app
2. Install and Configure Laravel Reverb
Install Reverb using Composer:
composer require laravel/reverb
php artisan install:broadcasting
This command will also generate the necessary configuration files for broadcasting and create echo.js
in your resources/js
directory.
Update your .env
file with the necessary Reverb configurations. You can generate application credentials from your dashboard on the service you are using.
BROADCAST_DRIVER=reverb
REVERB_APP_ID=your-app-id
REVERB_APP_KEY=your-app-key
REVERB_APP_SECRET=your-app-secret
3. Database Setup
We'll use a simple database structure for this example. Create a migration for a messages
table:
php artisan make:migration create_messages_table
Add the following code to the up
method of the generated migration file:
public function up()
{
Schema::create('messages', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
$table->text('message');
$table->timestamps();
});
}
Run the migrations:
php artisan migrate
4. Create the Message Model
Generate a Message model:
php artisan make:model Message
And define the relationship with the User model:
// app/Models/Message.php
use Illuminate\Database\Eloquent\Model;
class Message extends Model
{
protected $fillable = ['user_id', 'message'];
public function user()
{
return $this->belongsTo(User::class);
}
}
5. Create the Broadcasting Event
Generate an event that will be broadcast whenever a new message is sent:
php artisan make:event MessageSent
Update the MessageSent
event with the following:
// app/Events/MessageSent.php
namespace App\Events;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
use App\Models\Message;
class MessageSent implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $message;
/**
* Create a new event instance.
*/
public function __construct(Message $message)
{
$this->message = $message;
}
/**
* Get the channels the event should broadcast on.
*
* @return array<int, \Illuminate\Broadcasting\Channel>
*/
public function broadcastOn(): array
{
return [
new PresenceChannel('chat'),
];
}
}
6. Define the Broadcast Route
In your routes/channels.php
file, define the authorization logic for the chat
channel:
Broadcast::channel('chat', function ($user) {
return ['id' => $user->id, 'name' => $user->name];
});
This ensures that only authenticated users can join the chat channel.
7. Create the Chat Controller
Create a controller to handle chat-related logic:
php artisan make:controller ChatController
Define the methods for retrieving messages and sending new messages:
// app/Http/Controllers/ChatController.php
namespace App\Http\Controllers;
use App\Models\Message;
use Illuminate\Http\Request;
use App\Events\MessageSent;
class ChatController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
public function index()
{
return view('chat');
}
public function messages()
{
return Message::with('user')->latest()->take(10)->get();
}
public function sendMessage(Request $request)
{
$message = auth()->user()->messages()->create([
'message' => $request->message,
]);
broadcast(new MessageSent($message->load('user')))->toOthers();
return $message;
}
}
8. Set up Routes
Define the routes for your chat application in your routes/web.php
file:
// routes/web.php
use App\Http\Controllers\ChatController;
Route::get('/chat', [ChatController::class, 'index']);
Route::get('/messages', [ChatController::class, 'messages']);
Route::post('/messages', [ChatController::class, 'sendMessage']);
9. Create the Vue.js Component
Now, let's build the frontend using Vue.js. Create a new component file:
touch resources/js/components/Chat.vue
Add the following code to Chat.vue:
<template>
<div class="container">
<div class="row">
<div class="col-md-8 offset-md-2">
<div class="card">
<div class="card-header">Chat Room</div>
<div class="card-body" style="height: 400px; overflow-y: scroll;">
<ul class="list-unstyled">
<li v-for="message in messages" :key="message.id">
<strong>{{ message.user.name }}:</strong> {{ message.message }}
</li>
</ul>
</div>
<div class="card-footer">
<input type="text" class="form-control" v-model="newMessage" @keyup.enter="sendMessage">
<button class="btn btn-primary mt-2" @click="sendMessage">Send</button>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
messages: [],
newMessage: ''
};
},
mounted() {
this.fetchMessages();
Echo.join('chat')
.here((users) => {
console.log('Users online:', users);
})
.joining((user) => {
console.log(user.name + ' joined.');
})
.leaving((user) => {
console.log(user.name + ' left.');
})
.listen('MessageSent', (e) => {
this.messages.push(e.message);
});
},
methods: {
fetchMessages() {
axios.get('/messages').then(response => {
this.messages = response.data;
});
},
sendMessage() {
if (this.newMessage === '') {
return;
}
axios.post('/messages', { message: this.newMessage }).then(response => {
this.newMessage = '';
});
}
}
};
</script>
This component sets up a basic chat interface, retrieves messages, and sends new messages using Axios. It also utilizes Laravel Echo to listen for the MessageSent event and update the messages in real-time.
10. Compile Assets and Run
Finally, compile your assets and start the Laravel development server:
npm run dev
php artisan serve
That's it! You should now have a functional real-time chat application built with Laravel Reverb and Vue.js.
Conclusion
Laravel Reverb provides a straightforward yet powerful way to add real-time features to your Laravel applications. Paired with the flexibility of Vue.js, you can create engaging and interactive user experiences. This guide covered the fundamental steps to get your real-time chat application up and running. Explore the documentation further to discover more advanced features and customization options offered by Laravel Reverb and Vue.js.
Top comments (0)