Complete guide to achieving WebSocket real-time communication with Laravel Broadcast using Pusher, Laravel echo & Web socket
Published: 2020-12-21 17:01:04

---
title: Complete guide to achieving WebSocket real-time communication with Laravel Broadcast using Pusher, Laravel echo & Web socket
published: true
description: 
tags: 
//cover_image: https://direct_url_to_image.jpg
---


Nowadays, many advanced applications require real-time communication. Laravel has many inbuilt features to cover up the latest technologies and easy implementation. Laravel supports pusher, Redis, and socket.io to develop web socket interfaces.
I'm going to discuss how to set up a web socket communication channel using a self-hosted pusher, laravel echo, and laravel web socket. Using this tutorial, you would be able to configure the setup for your own chat application.

I've divided this tutorial into three steps,
1. Server-side setup
2. Client-side setup
3. Final Execution - Create Broadcast Event & Listen to channel

##Server-Side Setup

###Step 1
If you're using broadcasting events, you should install a pusher package. Laravel - version 5.3 and above has built-in support for Pusher Channels as a Broadcasting backend.
``` 
composer require pusher/pusher-php-server "~4.0" 
```

####Pusher Compatible Laravel Websockets
The laravel-websockets is a pure PHP, Pusher compatible WebSocket package for Laravel. This package allows you to leverage the full power of Laravel broadcasting without an external WebSocket provider or Node. For more information on installing and using this package, please consult its official documentation.
``` 
composer require beyondcode/laravel-websockets 
```
Change in .env
```
BROADCAST_DRIVER=pusher
APP_URL=http://127.0.0.1:8000
```
you should add the host and port configuration key to your config/broadcasting.php and add it to the pusher section. The default port of the Laravel WebSocket server is 6001.
```
'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'),
        'encrypted' => true,
        'host' => '127.0.0.1',
        'port' => 6001,
        'scheme' => 'http'
    ],
],
```
####Run Webocket & Test
```
php artisan websocket:server
```
Open this URL : http://127.0.0.1:8000/laravel-websockets

###Step 2
We use laravel broadcaster service, Let's uncomment following line from config/app.php 
```
App\Providers\BroadcastServiceProvider::class
```
###Step 3
By installing pusher package in step 1, We get a new configuration file in the config folder, Let's configure config/broadcasting.php
```
'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,
            ],
        ],
```

###Step 4
As we are not using pusher.com, It's time to change some dummy value in .env. The values shown below are just demoed purposes. It would be more realistic values on production. Why do we want to set dummy values here? You remember in step1 we install the pusher package that enables pusher on hour host, We're using the pusher broadcast driver supported by laravel so let's configure default environment variables.

```
PUSHER_APP_ID=123456
PUSHER_APP_KEY=scvbmzkmvc
PUSHER_APP_SECRET=xcnmcxdfgvc
PUSHER_APP_CLUSTER=mt1
BROADCAST_DRIVER=pusher
QUEUE_CONNECTION=sync
```

###Step 5
Don't forget to check csrf tag in app.blade.php. Channel authentication will need csrf-token.
```
<meta name="csrf-token" content="{{ csrf_token() }}">
```
##Configuration on Client Side
We're going to add client-side code that enables communication from HTTP to a socket server using laravel echo

###Step 1
You need client-side pusher js library that supports web browsers, web workers, Node.js and React Native.
```
npm install - save pusher-js
```
###Step 2
Laravel Echo is a JavaScript library that makes it painless to subscribe to channels and listen for events broadcast by Laravel.
npm install - save laravel-echo pusher-js

###Step 3
Comment Vue.js in resources/js/app.js, if you're not using it. 

###Step 4
Remove comment from resources/js/bootstrap.js and add Hosts 
```
import Echo from 'laravel-echo'; 
window.Pusher = require('pusher-js'); 
window.Echo = new Echo({
     broadcaster: 'pusher',
     key: process.env.MIX_PUSHER_APP_KEY,
     cluster: process.env.MIX_PUSHER_APP_CLUSTER,
     forceTLS: true,
     wsHost: window.location.hostname,
     wsPort: 6001
});
```

Your laravel-echo-server.json should look like this,
```
{
	"authHost": "http://127.0.0.1:8000",
	"authEndpoint": "/broadcasting/auth",
	"clients": [
		{
			"appId": "626725232e738e727",
			"key": "4ac7dd96bc51f1f345344381230f2644737d"
		}
	],
	"database": "redis",
	"databaseConfig": {
		"redis": {
      "port": "6379",
      "host": "127.0.0.1",
      "keyPrefix": ""
		}
	},
	"devMode": true,
	"host": null,
	"port": "8081",
	"protocol": "http",
	"socketio": {},
	"secureOptions": 67108864,
	"sslCertPath": "",
	"sslKeyPath": "",
	"sslCertChainPath": "",
	"sslPassphrase": "",
	"subscribers": {
		"http": true,
		"redis": true
	},
	"apiOriginAllow": {
		"allowCors": true,
		"allowOrigin": "http://localhost:80",
		"allowMethods": "GET, POST",
		"allowHeaders": "Origin, Content-Type, X-Auth-Token, X-Requested-With, Accept, Authorization, X-CSRF-TOKEN, X-Socket-Id"
	}
}
```

###Step 5
Compile client-side js and get ready!!!
```
Run - npm run dev
```

##Final Execution - Create Broadcast Event & Listen to channel

###Step 1 - Create Event
Create TestEvent.php in App/Events
```
<?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;
class TestEvent implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $message;
public $count;
/**
* Create a new event instance.
*
* @return void
*/
public function __construct()
{
$this->message =  'hello';
$this->count = 1;
}
/**
* Get the channels the event should broadcast on.
*
* @return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn(){
    return new Channel('test');
}
public function broadcastWith(){
    return ['message' => str_random(15)];
}
}
```

###Step 2- Listen channel in App.blade.php
```
<script src="{{ asset('/js/app.js') }}"></script>
<script>
Echo.channel('private-test')
    .listen('TestEvent', (e) => {
         console.log(e);
    })
</script>
```
Verify CSRF token once again!! Server-side setup - Step 5
Execution

####1. Start laravel echo server
```
laravel-echo-server start
```
####2. Start websocket server
```
php artisan websocket:server
php artisan queue:work 
```
####3. Recompile app.js
```
npm run dev
```
####4. Fire an event using php tinker, you should have a console log in the browser.
```
php artisan tinker
event(new \App\Events\TestEvent());
```
##Conclusion
We've implemented a basic setup of all components required to listen to the channel for real-time communication. We've seen how to set up a web socket with help of a pusher library using laravel broadcasting on the self-host.