A Laravel 11-based messaging platform featuring secure authentication, real-time communication via WebSockets, and persistent message history.
- User Authentication: Secure registration and login powered by Laravel Breeze (Blade).
- Protected Access: Restricted functionality for authenticated users only.
- Member Directory: View a complete list of registered users upon login.
- Real-Time Chat: Instant messaging between users without page reloads.
- Message Persistence: All messages (sender, receiver, text, and timestamp) are stored in MySQL.
- Offline Message Sync: Users receive missed messages upon their next login.
- Event-Driven Architecture: Built using Laravel Events and Broadcasting.
- Framework: Laravel 11.31+ (PHP 8.3+)
- Frontend: Blade Templates + Laravel Echo
- Database: MySQL 8+
- Broadcasting Server: Laravel Reverb
- Queue/Cache Store: Redis (via
predis) - Containerization: Laravel Sail (Docker)
This is the recommended way if you have Docker installed.
- Clone the repository:
git clone <repository-url> cd <project-folder>
- Install PHP dependencies via Docker:
docker run --rm \ -u "$(id -u):$(id -g)" \ -v "$(pwd):/var/www/html" \ -w /var/www/html \ laravelsail/php83-composer:latest \ composer install --ignore-platform-reqs
- Configure Environment:
cp .env.example .env
- Start the containers:
./vendor/bin/sail up -d
- Initialize Application:
./vendor/bin/sail artisan key:generate ./vendor/bin/sail artisan migrate ./vendor/bin/sail npm install ./vendor/bin/sail npm run build
- Initialize Reverb Broadcasting Server:
./vendor/bin/sail artisan reverb:start
- Initialize queue worker
./vendor/bin/sail artisan queue:work
- Clone the repository:
composer install npm install
- Configure Environment:
cp .env.example .env
- Generate Application Key:
php artisan key:generate php artisan migrate npm install npm run build
- Start the server:
To start all services (Web Server, WebSockets, Queues, and Vite) simultaneously:
composer run dev
The core functionality relies on the following structure for the messages table:
Stores all communication history between users.
| Field | Type | Description |
|---|---|---|
id |
BigInt (PK) | Unique message identifier. |
sender_id |
ForeignId | ID of the user who sent the message (refers to users.id). |
receiver_id |
ForeignId | ID of the user receiving the message (refers to users.id). |
text |
Text | The content of the message. |
is_read |
Boolean | Read status (default: false). |
created_at |
Timestamp | Date and time the message was created. |
updated_at |
Timestamp | Date and time of the last update. |
The system uses a dedicated Event class MessageSent to handle real-time delivery.
When a message is sent, the event is dispatched with the following characteristics:
ShouldBroadcastInterface: Tells Laravel to send this event to the broadcasting driver (Reverb via Redis) instead of just handling it locally.- Eager Loading: The constructor automatically loads the
senderrelationship ($this->message->load('sender')), ensuring the recipient's UI can display who the message is from. - Private Channel: It uses a secure
PrivateChannel, namedmessenger.user.{receiver_id}. Only the intended recipient can listen to this channel.
- Dispatch: The
MessageSentevent is triggered in the Controller after saving the message to MySQL. - Queue: The event is pushed to Redis (via the
predisclient). - Broadcast: Laravel Reverb picks up the event from Redis and broadcasts it to the specific WebSocket connection.
- Frontend: Laravel Echo (on the client side) listens for the
MessageSentevent on themessenger.user.{id}channel and updates the chat UI in real-time.
You can create a new account manually by visiting:
http://{host}/register

To quickly test the messaging system without manual registration, run the following command to populate the database with 5 pre-configured users:
# Using Sail
./vendor/bin/sail artisan migrate:fresh --seed
# Locally
php artisan migrate:fresh --seedTest Credentials:
alice@example.combob@example.comcharlie@example.comdavid@example.comeve@example.com- Password:
password(for all)
After registration or seeding, navigate to:
http://{host}/login

Once authenticated, you will see the Dashboard containing the list of all registered users. You can immediately start a real-time chat with any of them.

The application provides a seamless experience for both active and returning users through dynamic UI updates.
- Global Alerts: When an authenticated user is anywhere on the dashboard or in another chat, new incoming messages trigger a popup notification in the top-right corner of the screen.

- Instant Chat Updates: If a user is currently in an active chat session with the sender, new messages appear instantly in the message bubble list without requiring a page reload.

The system tracks the "read/unread" status of messages to ensure no communication is missed:
- Automatic Counting: If a user does not click on a popup notification or is not currently viewing that specific chat, the message remains "unread".
- Visual Indicators: A notification badge with a numeric counter appears next to the user's name in the contact list, showing the total number of unread messages from that specific person.

- Offline Synchronization: When a user logs in after being offline, the system automatically calculates unread messages from the database and displays the corresponding badges immediately.

