0%

Laravel with Redis and Socket.io

Laravel with Redis and Socket

Redis

https://laravel.com/docs/5.3/redis

$ redis-cli

1
2
# .env
CACHE_DRIVER=redis

core
vendor/laravel/framework/src/Illuminate/Cache/RedisStore.php

1
2
3
4
5
6
7
// routes/web.php
use Illuminate\Support\Facades\Redis;
...
Route::get('/', function () {
Redis::set('name', 'gan');
return Redis::get('name');
});
1
2
3
4
5
// routes/web.php
Route::get('/', function () {
Cache::put('foo', 'bar', 10);
return Cache::get('foo');
});

Example

Goal

  1. Publish event with Redis
  2. Node.js + Redis subscribes to the event
  3. Use socket.io to emit to all clients.

npm install socket.io ioredis --save

BroadCast

1
2
# .env
BROADCAST_DRIVER=redis

Files

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
<?php
// php artisan make:event UserSignedUp
// app/Events/UserSignedUp.php
namespace App\Events;
use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class UserSignedUp implements ShouldBroadcast
{
use InteractsWithSockets, SerializesModels;
public $username;
public $age = 30;
/**
* Create a new event instance.
*
* @return void
*/
public function __construct($username)
{
$this->username = $username;
}
/**
* Get the channels the event should broadcast on.
*
* @return Channel|array
*/
public function broadcastOn()
{
// return new PrivateChannel('test-channel');
return ['test-channel'];
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
// route/web.php
use App\Events\UserSignedUp;
Route::get('/', function () {
// 1. Publish event with Redis
// $data = [
// 'event' => 'UserSignedUp',
// 'data' => [
// 'username' => 'JohnDoe'
// ]
// ];
// 2. Node.js + Redis subscribes to the event = sock.js
// Redis::publish('test-channel', json_encode($data));
event(new UserSignedUp( Request::query('name') ));
return view('welcome');
});
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
<!-- welcome.blade.php -->
<!DOCTYPE html>
<html>
<head>
<title>Real time</title>
</head>
<body>
<div id="app">
<h1>New User</h1>
<p>Client->POST chat trigger event->broadcast to user</p>
<ul>
<li v-for="user in users">
@{{ user }}
</li>
</ul>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-resource/1.0.3/vue-resource.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.7.2/socket.io.min.js"></script>
<script type="text/javascript">
var socket = io('http://localhost:3000');
new Vue({
el: '#app',
data: {
users: [],
},
mounted: function() {
// 'test-channel:UserSignedUp'
socket.on('test-channel:App\\Events\\UserSignedUp', function(data) {
this.users.push(data.username)
// console.log(data)
}.bind(this))
}
})
</script>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// socket.js
var server = require('http').Server();
var io = require('socket.io')(server);
var Redis = require('ioredis');
var redis = new Redis();
redis.subscribe('test-channel');
redis.on('message', function (channel, message) {
console.log(channel, message);
// 3. Use socket.io to emit to all clients.
message = JSON.parse(message);
io.emit(channel + ':' + message.event, message.data); // test-channel:UserSignedUp
});
server.listen(3000);