Building a real-time chat application with Laravel and Pusher

Written by:

Introduction

Real-time chat applications have become an essential part of many websites and mobile applications. They provide a quick and efficient way for users to communicate with each other, and can be used for a wide range of applications, from customer support to team collaboration.

In this post, we’ll explore how to build a real-time chat application using Laravel, one of the most popular PHP web frameworks, and Pusher, a cloud-based messaging platform. We’ll cover all the key concepts you’ll need to know, from setting up the Laravel project to building the backend and testing the application.

First, we’ll explain how to set up the Laravel project and configure it for real-time communication. We’ll then show you how to build the chat interface using Laravel’s Blade templates and add real-time messaging capabilities using Pusher. We’ll also explore how to use Vue.js to create a responsive and interactive chat interface.

Next, we’ll dive into building the backend of the chat application. We’ll explain how to create the necessary routes and controllers to handle chat messages, how to use Laravel’s event system to broadcast messages in real-time, and how to persist chat messages in a database using Laravel’s Eloquent ORM.

Finally, we’ll discuss the importance of testing and show you how to use PHPUnit and Laravel’s testing tools to test the chat application. We’ll also provide best practices for testing real-time applications.

By the end of this post, you’ll have a solid understanding of how to use Laravel and Pusher to build a real-time chat application from scratch. Let’s get started!

Setting up the Laravel project

To get started, we’ll need to set up a new Laravel project and configure it for real-time communication. Here are the steps you’ll need to follow:

A. Installing and setting up Laravel

  1. First, make sure you have PHP and Composer installed on your system.
  2. Open up a terminal or command prompt and navigate to the directory where you want to create the new Laravel project.
  3. Run the following command to create a new Laravel project:
composer create-project --prefer-dist laravel/laravel your-project-name
  1. Once the project is created, navigate into the project directory and run the following command to start the development server:
php artisan serve
  1. Open up your web browser and navigate to http://localhost:8000 to see the Laravel welcome screen.

B. Configuring the project for real-time communication

Now that we have a basic Laravel project up and running, we’ll need to configure it for real-time communication using Pusher. Here’s what you need to do:

  1. First, sign up for a free account on the Pusher website.
  2. Once you’ve signed up, create a new app in your Pusher dashboard.
  3. Take note of the app credentials, including the app ID, key, and secret.
  4. Next, open up your Laravel project and install the official Pusher PHP SDK using Composer:
composer require pusher/pusher-php-server
  1. After installing the SDK, open up the .env file in your Laravel project and add the following lines:
PUSHER_APP_ID=your-app-id
PUSHER_APP_KEY=your-app-key
PUSHER_APP_SECRET=your-app-secret
PUSHER_APP_CLUSTER=mt1
  1. Replace your-app-id, your-app-key, and your-app-secret with the corresponding values from your Pusher app dashboard.
  2. Save the .env file and run the following command to clear the Laravel configuration cache:
php artisan config:cache

C. Adding authentication to the project

To prevent unauthorized access to our chat application, we’ll need to add authentication to our Laravel project. Here’s how to do it:

  1. Run the following command to generate the authentication scaffolding:
php artisan make:auth
  1. This will generate the necessary routes, controllers, and views for user registration and authentication.
  2. Next, run the following command to create a migration for the users table:
php artisan make:migration create_users_table --create=users
  1. This will create a new migration file in the database/migrations directory. Open up the migration file and add the necessary columns for the users table, such as name, email, and password.
  2. Run the migration using the following command:
php artisan migrate
  1. Now, users will be able to register and log in to your Laravel application using the built-in authentication system.

With the Laravel project set up and configured, we’re ready to start building the real-time chat application!

Creating the chat interface

Now that we have our Laravel project set up and configured for real-time communication using Pusher, we can start building the chat interface. Here’s how to do it:

A. Creating the chat interface with Laravel Blade templates

  1. First, create a new Blade template for the chat interface. You can do this by creating a new file in the resources/views directory of your Laravel project, such as chat.blade.php.
  2. In the new template, add the HTML and CSS necessary to display the chat interface. This can include a header with a list of active chat rooms, a main chat area with a list of messages, and a form for sending new messages.
  3. To display the list of messages, you can use a @foreach loop in your Blade template to iterate over the messages and display them in the chat area.
  4. To add real-time messaging capabilities, we’ll need to use Pusher to update the chat interface whenever a new message is sent. We’ll cover this in more detail in the next section.

B. Adding real-time messaging capabilities with Pusher

  1. To add real-time messaging capabilities, we’ll need to listen for new messages on the Pusher channel and update the chat interface whenever a new message is received. We can do this using JavaScript in our Blade template.
  2. First, include the Pusher JavaScript SDK in your Blade template using the following code:
<script src="https://js.pusher.com/7.0/pusher.min.js"></script>
  1. Next, create a new Pusher instance and subscribe to the channel for the current chat room. Here’s an example:
<script>
    const pusher = new Pusher('{{ env("PUSHER_APP_KEY") }}', {
        cluster: '{{ env("PUSHER_APP_CLUSTER") }}'
    });

    const channel = pusher.subscribe('chat-room-{{ $roomId }}');
</script>
  1. Now, we can listen for new messages on the channel and update the chat interface whenever a new message is received. Here’s an example:
<script>
    channel.bind('new-message', function(data) {
        // Update the chat interface with the new message
    });
</script>
  1. In the new-message event, we’ll receive the new message data from Pusher. We can use this data to update the chat interface with the new message using JavaScript.

C. Using Vue.js to build a responsive and interactive chat interface

  1. While Laravel’s Blade templates are great for building static web pages, they can be a bit limiting when it comes to building dynamic and interactive user interfaces.
  2. To build a more responsive and interactive chat interface, we can use a JavaScript framework like Vue.js.
  3. First, add the Vue.js framework to your Laravel project using the following command:
npm install vue
  1. Next, create a new Vue component for the chat interface. This can include a template for displaying the chat messages, as well as methods for sending and receiving messages using Pusher.
  2. To display the Vue component in your Blade template, you can use a @verbatim directive to avoid conflicts between Blade and Vue syntax. Here’s an example:
@verbatim
    <div id="chat">
        <chat-room :roomId="{{ $roomId }}"></chat-room>
    </div>
@endverbatim

Building the backend

In order for our real-time chat application to work, we need to create the necessary routes, controllers, and database tables to handle chat messages. Here’s how to do it:

A. Creating routes and controllers to handle chat messages

  1. First, create a new route in your Laravel project’s routes/web.php file to handle incoming chat messages. Here’s an example:
Route::post('/chat/message', [ChatController::class, 'sendMessage']);
  1. Next, create a new controller for handling chat messages. This controller will be responsible for validating incoming chat messages, broadcasting them to other users, and persisting them in the database. Here’s an example:
class ChatController extends Controller
{
    public function sendMessage(Request $request)
    {
        // Validate incoming chat message
        $validator = Validator::make($request->all(), [
            'message' => 'required',
            'room_id' => 'required|exists:chat_rooms,id',
            'user_id' => 'required|exists:users,id',
        ]);

        if ($validator->fails()) {
            return response()->json(['error' => $validator->errors()], 400);
        }

        // Broadcast message to other users
        $message = new ChatMessage($request->all());
        event(new ChatMessageSent($message));

        // Save message to database
        $message->save();

        return response()->json(['message' => 'Message sent'], 200);
    }
}
  1. In the sendMessage method of the controller, we first validate the incoming chat message using Laravel’s built-in validation system. If the validation fails, we return an error response.
  2. Next, we broadcast the message to other users using Laravel’s event system. We’ll cover this in more detail in the next section.
  3. Finally, we save the message to the database using Laravel’s Eloquent ORM.

B. Using Laravel’s event system to broadcast messages in real-time

  1. Laravel’s event system allows us to broadcast events to other users in real-time using Pusher. To use the event system, we first need to define the event and listener.
  2. First, create a new event class for the ChatMessageSent event. Here’s an example:
class ChatMessageSent implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public $chatMessage;

    public function __construct(ChatMessage $chatMessage)
    {
        $this->chatMessage = $chatMessage;
    }

    public function broadcastOn()
    {
        return new PrivateChannel('chat-room-' . $this->chatMessage->room_id);
    }
}
  1. In the ChatMessageSent event class, we define the broadcastOn method to specify the Pusher channel that the event should be broadcast on. In this case, we’re using a private channel for the current chat room.
  2. Next, we create a new listener for the ChatMessageSent event. Here’s an example:
class ChatMessageSentListener
{
    public function handle(ChatMessageSent $event)
    {
        $message = $event->chatMessage;

        // Broadcast message to other users
        broadcast(new ChatMessageSentEvent($message))->toOthers();
    }
}

In the ChatMessageSentListener class, we define the handle method to broadcast the ChatMessageSent event to other users in the same chat room.

Testing the chat application

Testing is an essential part of any software development process. When it comes to real-time applications, testing becomes even more important since there are more moving parts that need to work together seamlessly. In this section, we’ll cover how to test our real-time chat application using Laravel’s testing tools.

A. The importance of testing and how to write tests for a real-time chat application

Testing is crucial for ensuring the stability, reliability, and security of our chat application. By testing our application, we can catch bugs and errors before they make it to production, which can save us a lot of time and headaches down the road.

To write tests for our real-time chat application, we’ll use PHPUnit, which is a popular testing framework for PHP. PHPUnit provides a rich set of tools for writing unit, integration, and functional tests.

B. Using PHPUnit and Laravel’s testing tools to test the chat application

To test our real-time chat application, we’ll use Laravel’s built-in testing tools, which provide an easy and convenient way to write tests for our application.

  1. First, create a new test case for the chat application. Here’s an example:
class ChatTest extends TestCase
{
    use RefreshDatabase;

    /** @test */
    public function a_user_can_send_a_chat_message()
    {
        // Arrange
        $room = ChatRoom::factory()->create();
        $user = User::factory()->create();

        $data = [
            'message' => 'Hello, world!',
            'room_id' => $room->id,
            'user_id' => $user->id,
        ];

        // Act
        $response = $this->json('POST', '/chat/message', $data);

        // Assert
        $response->assertStatus(200);
        $this->assertDatabaseHas('chat_messages', $data);
    }
}
  1. In the test case, we first create a new chat room and user using Laravel’s factory system.
  2. Next, we create some data for the chat message and send it to the server using the json method.
  3. Finally, we assert that the server responds with a 200 status code and that the chat message is saved in the database.

C. Best practices for testing real-time applications

When testing real-time applications, there are a few best practices that we should keep in mind:

  1. Test both the server and client sides of the application. In our case, we should test that the server is handling chat messages correctly and that the client is receiving and displaying messages in real-time.
  2. Use a combination of unit, integration, and functional tests to cover all aspects of the application.
  3. Test for edge cases, such as sending invalid or malformed data, to ensure that the application can handle unexpected inputs.
  4. Mock external dependencies, such as Pusher, to isolate our tests and make them more reliable.
  5. Use continuous integration (CI) tools, such as Travis CI or CircleCI, to automatically run tests whenever code is pushed to the repository. This can catch errors early and ensure that the application is always in a stable state.

Conclusion

In this post, we’ve covered how to build a real-time chat application with Laravel and Pusher. We’ve seen how easy it is to set up real-time communication in Laravel using Pusher, and how to create a responsive and interactive chat interface using Vue.js.

We’ve also discussed how to build the backend of the application, handle chat messages, and persist data in a database. Finally, we’ve talked about the importance of testing and how to write tests for a real-time chat application using Laravel’s testing tools.

We encourage you to experiment with Laravel and Pusher to build your own real-time chat applications. With Laravel’s powerful features and Pusher’s real-time communication capabilities, the possibilities are endless.

If you need professional help, consider hiring Laravel developers to help you build your real-time chat application. Our team of expert Laravel developers has years of experience building custom web applications using Laravel and other modern technologies. Contact us today to learn more.

Additional resources:

Leave a comment

Design a site like this with WordPress.com
Get started