私有广播频道

既然是私有,就不再是前一篇中的公共频道,针对所有所有,这里私有的频道,就是根据个体了

创建数据库
1
create database events
构建 Auth
1
php artisan make:auth
项目中配置好数据库
1
2
3
4
5
6
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=events
DB_USERNAME=root
DB_PASSWORD=
生成结构
1
2
3
4
5
6
$ php artisan migrate 
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_000000_create_users_table
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated: 2014_10_12_100000_create_password_resets_table
通过自带的界面,注册一个账号
1
2
3
4
5
6
7
8
9
10
11
12
mysql> use events
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> select id,name,email from users where id = 1;
+----+------+-------------+
| id | name | email |
+----+------+-------------+
| 1 | dev | dev@dev.dev |
+----+------+-------------+
1 row in set (0.00 sec)
创建一个Event
1
php artisan make:event PrivateDevEvent
编辑 project/app/Events/PrivateDevEvent.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<?php

namespace App\Events;

use App\User;
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 PrivateDevEvent implements ShouldBroadcast
{
// 用户模型
public $user;

use Dispatchable, InteractsWithSockets, SerializesModels;

/**
* Create a new event instance.
*
* @return void
*/
public function __construct(User $user)
{
//接收一个用户模型
$this->user = $user;
}

/**
* Get the channels the event should broadcast on.
*
* @return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
//私有频道,绑定在用户ID
return new PrivateChannel('member.' . $this->user->id);
}
}
测试的视图,我使用welcome.blade.php,为了获取user id,中间件我加上auth
1
2
3
Route::get('/', function () {
return view('welcome');
})->middleware('auth');
视图文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="csrf-token" content="{{csrf_token()}}">
<title>test page</title>
<script>
//定义全局变量,保存ID
window.member = {!! json_encode([
'id' => auth()->check() ? auth()->user()->id : null,
]) !!};
</script>
</head>
<body>
<div id="app">
test page
</div>
</body>
<script src="{{ asset('js/app.js') }}"></script>
<script>
//监听在event中定义的channel名称
window.Echo.private('member.' + window.member.id)
.listen('PrivateDevEvent', (e) => {
console.log(e);
});
</script>
</html>
route/channels.php定义一个授权
1
2
3
4
5
//注意监听的channel名称一定要对应
Broadcast::channel('member.{id}', function ($user, $id) {
//返回true,验证即可通过
return (int) $user->id === (int) $id;
});
差不多了,浏览器访问一下验证一下是否可行
1
2
3
//laravel-echo-server 提示验证通过
[16:34:03] - 4xB2G_USanJq9kgxAAAC authenticated for: private-member.1
[16:34:03] - 4xB2G_USanJq9kgxAAAC joined channel: private-member.1
保持监听
1
php artisan queue:listen --tries=1
这次我们定义一个路由,来发送广播
1
2
3
4
//发送广播
Route::get('/pusher', function () {
broadcast(new \App\Events\PrivateDevEvent(Auth::user()));
})->middleware('auth');
访问 http://echo.test/pusher
1
2
3
4
5
6
7
//echo server
Channel: private-member.1
Event: App\Events\PrivateDevEvent

//监听
Channel: private-member.1
Event: App\Events\PrivateDevEvent
页面响应

QQ20181019-164324@2x.png

上篇讲到过一个场景,当一个用户购买某个商品后进行广播通知,尅尝试一下更高级的特性,将事件绑定在model中,当一个订单创建时,广播一次,订单完成时,再次广播一次