# Laravel broadcast (socket.io+redis)
>製作:Tinn
>參考:Google各位大神、laravel官網...
## 1. 環境需求安裝
### **Laravel Echo Server Socket.io 服務端**
```composer require predis/predis```
```run npm install -g laravel-ehco-server```
```uncomment``` <font color="red">App\providers\BroadcastServiceProvider::class</font> ``` in config/app.php```
## 2. 修改程式碼
### **反註解BroadcastServiceProvider**
打開config/app.php 找到 'provides' 屬性,將註解打開
```php=
'providers' => [
App\Providers\AppServiceProvider::class,
App\Providers\AuthServiceProvider::class,
//App\Providers\BroadcastServiceProvider::class,
App\Providers\EventServiceProvider::class,
App\Providers\RouteServiceProvider::class,
App\Providers\SqlLogServiceProvider::class,
]
```
### **修改.env**
<pre>BROADCAST_DRIVER=<font color="red">redis</font>
REDIS_HOST=redis
REDIS_PASSWORD=null
REDIS_PORT=6379</pre>
### **設置廣播路由**
* 打開廣播路由文件 ```routes/channels.php``` 我們增加一個新的廣播通道 news
```<?php
/*
|--------------------------------------------------------------------------
| Broadcast Channels
|--------------------------------------------------------------------------
|
| Here you may register all of the event broadcasting channels that your
| application supports. The given channel authorization callbacks are
| used to check if an authenticated user can listen to the channel.
|
*/
Broadcast::channel('App.User.{id}', function ($user, $id) {
return (int) $user->id === (int) $id;
});
Broadcast::channel('news.{id}', function ($user, $id) {
// return (int) $user->id === (int) $id;
// logger('id ID: ' . $id);
return true;
});
```
**設為true 代表無論收聽者是誰都會接收以 ```.{id}``` 為該收聽者能接收到**
* 如使用私人頻道請於app/Providers/BroadcastProvider中boot修改註解Broadcast::routes()並增加middlware驗證
```php=
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Broadcast;
class BroadcastServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
// Broadcast::routes();
Broadcast::routes(['middleware' => ['check.jwt']]);
require base_path('routes/channels.php');
}
}
```
### **實作一個Event**
* php artisan make:event NewsMessage 創建後進行以下修改:
* 增加對ShouldBroadcast的實現
* 修改broadcastOn方法,使用私人廣播通道news
```php=
namespace App\Events;
use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class NewsMessage implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $to;
public $notify;
public $time;
public $readPerson;
public $type;
/**
* Create a new event instance.
*
* @return void
*/
public function __construct($to, $notify)
{
$this->to = $to;
$this->notify = $notify;
$this->time = now();
}
/**
* Get the channels the event should broadcast on.
*
* @return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
return new PrivateChannel('news.' . $this->to);
// return new PrivateChannel('channel-name');
}
public function broadcastWith()
{
return [
'time' => now(),
'receive' => $this->to,
'notify' => $this->notify,
];
}
}
```
* 撰寫發送事件程式碼
```php=
public function sendNotifyAction($recipient, $message)
{
broadcast(new NewsMessage($recipient, $message));
}
```
### **Laravel Echo Client - Socket.io 客户端**
```npm install --save laravel-echo```
```npm install --save socket.io-client```
* Vue.js 中如何使用??
```javascript=
import Echo from 'laravel-echo'
import io from 'socket.io-client';
const EchoClient = new Echo({
broadcaster: 'socket.io',
host: window.location.hostname + ':6001',
client: io,
auth: {
headers: {
// 用於私人頻道
Authorization: 'Bearer ' + localStorage.apiToken,
},
},
});
// 公開频道
EchoClient.channel('news')
.listen('NewsMessage', function (event) {
console.log(event);
});
// 私有频道
/* private('name')需與後端頻道名稱相同
* listen 需與事件class名稱相同*/
EchoClient.private('news.'+this.id)
.listen('NewsMessage', function (event) {
console.log(event);
});
```
### **啟動**
* 初始化laravel-echo-server
```run laravel-echo-server init```
<img src='https://i.imgur.com/eyaDgXv.png'>
* 啟動laravel-echo-server
<img src='https://i.imgur.com/erjHZKw.png'>
###### tags: `laravel`