Laravel, Redis и Socket.io

Установка

На стороне сервера требуются следующие пакеты — через npm:

npm install ioredis socket.io --save

Для PHP с помощью composer:

composer require predis/predis

Настройка

В .env файле прописываем CACHE_DRIVER=redis или в config/cache.php 'default' => env('CACHE_DRIVER', 'file'),.

Действия на стороне сервера

В корневом каталоге проекта создаем файл server.js для использования с node.js и прописываем в него следующий код:

var server = require('http').Server();
var io = require('socket.io')(server);
var Redis = require('ioredis');
var redis = new Redis();
//Подписываемся на канал
redis.subscribe('some-channel-name');
redis.on('some-message-name', function(channel, message) {
    message = JSON.parse(message);
    //Посылаем на front-end
    io.emit(channel + ':' + message.event, message.data);
});
//Выбираем номер порта
server.listen(3000);

Теперь создаем класс события в Laravel с интерфейсом ShouldBroadcast, например регистрация нового пользователя:

class UserSignedUp extends Event implements ShouldBroadcast
{
    use SerializesModels;
    public $username;
    public function __construct($username)
    {
        $this->username = $username;
    }
    public function broadcastOn()
    {
        return ['test-channe'];
    }
        //Транслировать короткое имя события без полного namespace path
    public function broadcastAs()
    {
        return ['UserSignedUp'];
    }
}

Чтобы транслировать данное событие достаточно всего одной строки кода:

event(new UserSignedUp("new_user_name"));

как альтернатива, есть API самого Redis, с помощью которого можно транслировать данные и без Laravel. Выглядеть это может примерно так:

$data = [
    'event' => 'UserSignedUp',
    'data' => [
        'username' => 'new_user'
    ]
];
Redis::publish('some-channel-namel', json_encode($data));

На стороне клиента

Импортируем библиотеки socket.io и vue.js:

<script src="https://cdn.jsdelivr.net/vue/1.0.24/vue.js"></script>
<script src="https://cdn.jsdelivr.net/socket.io-client/1.3.2/socket.io.min.js"></script>

Инициализируем Vue:

new Vue({
    el: '#chat',
    data: {
        users: [],
        socket: io("http://192.168.10.10:3000") // В данном случае я использую homestead и порт 3000
    },
    ready: function() {
        this.socket.on('some-channel-namel:UserSignedUp', function(data) {
            this.users.push(data.username);
        }.bind(this));
    }
});

Наконец отображаем список новых пользователей, обновляемый в режиме реального времени:

<div id="chat">
    <h1>Новые пользователи</h1>
    <ul>
        <li v-for="user in users" track-by="$index">@{{ user }}</li>
    </ul>
</div>