Building a Real-Time Chat Application with Laravel and Pusher
Introduction
In this tutorial, we will build a real-time chat application using Laravel and Pusher. This guide assumes you have a senior-level understanding of Laravel and real-time messaging systems. We will cover setting up Laravel, integrating Pusher, and implementing real-time notifications. By the end, you’ll have a fully functional chat application with code examples.
Prerequisites
Before we start, make sure you have the following:
- PHP 7.3+ and Composer installed
- Laravel 8+ installed
- Pusher account
- Basic understanding of Laravel, JavaScript, and Pusher
Setting Up Laravel Project
First, create a new Laravel project:
composer create-project --prefer-dist laravel/laravel chat-app
Navigate into your project directory:
cd chat-app
Set up your .env
file with your database configuration:
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=chat_app
DB_USERNAME=root
DB_PASSWORD=
Run the migrations to create the necessary tables:
php artisan migrate
Setting Up Pusher
Install the Pusher PHP SDK:
composer require pusher/pusher-php-server
Register your Pusher credentials in the .env
file:
PUSHER_APP_ID=your-pusher-app-id
PUSHER_APP_KEY=your-pusher-app-key
PUSHER_APP_SECRET=your-pusher-app-secret
PUSHER_APP_CLUSTER=mt1
Configure broadcasting settings in config/broadcasting.php
:
'default' => env('BROADCAST_DRIVER', 'pusher'),
'connections' => [
'pusher' => [
'driver' => 'pusher',
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'app_id' => env('PUSHER_APP_ID'),
'options' => [
'cluster' => env('PUSHER_APP_CLUSTER'),
'useTLS' => true,
],
],
],
Creating the Models and Migrations
We’ll need User
and Message
models. First, create the Message
model and migration:
php artisan make:model Message -m
Edit the migration file to define the schema:
public function up()
{
Schema::create('messages', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->onDelete('cascade');
$table->text('message');
$table->timestamps();
});
}
Run the migration:
php artisan migrate
Setting Up Event Broadcasting
Create a new event for message broadcasting:
php artisan make:event MessageSent
Edit the event file app/Events/MessageSent.php
:
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Queue\SerializesModels;
use App\Models\Message;
class MessageSent implements ShouldBroadcast
{
use InteractsWithSockets, SerializesModels;
public $message;
public function __construct(Message $message)
{
$this->message = $message;
}
public function broadcastOn()
{
return new PrivateChannel('chat');
}
}
Creating the Message Controller
Create a controller to handle message sending:
php artisan make:controller MessageController
Edit app/Http/Controllers/MessageController.php
:
use App\Events\MessageSent;
use App\Models\Message;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class MessageController extends Controller
{
public function sendMessage(Request $request)
{
$message = Message::create([
'user_id' => Auth::id(),
'message' => $request->message
]);
broadcast(new MessageSent($message))->toOthers();
return response()->json(['status' => 'Message Sent!']);
}
public function fetchMessages()
{
return Message::with('user')->get();
}
}
Setting Up Routes
Add the following routes to routes/web.php
:
use App\Http\Controllers\MessageController;
Route::get('/messages', [MessageController::class, 'fetchMessages']);
Route::post('/messages', [MessageController::class, 'sendMessage']);
Creating the Frontend
In resources/views/welcome.blade.php
, add the following HTML and JavaScript:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Chat App</title>
<meta name="csrf-token" content="{{ csrf_token() }}">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<script src="https://js.pusher.com/7.0/pusher.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.0/axios.min.js"></script>
</head>
<body>
<div class="container">
<div class="row" id="app">
<div class="col-12">
<h1>Chat App</h1>
<ul id="messages" class="list-group">
<!-- Messages will be loaded here -->
</ul>
<form id="message-form">
<div class="form-group">
<input type="text" id="message-input" class="form-control" placeholder="Type your message...">
</div>
<button type="submit" class="btn btn-primary">Send</button>
</form>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const messagesElement = document.getElementById('messages');
const messageForm = document.getElementById('message-form');
const messageInput = document.getElementById('message-input');
// Fetch messages
axios.get('/messages').then(response => {
response.data.forEach(message => {
addMessage(message);
});
});
// Listen for new messages
Echo.private('chat')
.listen('MessageSent', (e) => {
addMessage(e.message);
});
// Add message to list
function addMessage(message) {
const messageElement = document.createElement('li');
messageElement.classList.add('list-group-item');
messageElement.textContent = message.user.name + ': ' + message.message;
messagesElement.appendChild(messageElement);
}
// Send message
messageForm.addEventListener('submit', function(e) {
e.preventDefault();
const message = messageInput.value;
axios.post('/messages', { message }).then(response => {
messageInput.value = '';
});
});
});
</script>
<script src="//{{ Request::getHost() }}:6001/socket.io/socket.io.js"></script>
<script src="{{ mix('js/app.js') }}"></script>
</body>
</html>
Conclusion
In this tutorial, we built a real-time chat application using Laravel and Pusher. We covered setting up Laravel, integrating Pusher, creating models and controllers, setting up event broadcasting, and creating a frontend for real-time messaging. With this foundation, you can expand the application with features like private messaging, notifications, and more advanced user interactions. Happy coding!