Laravel Echo (Websocket ブロードキャスト)を試す
最近PHPのフレームワークを触る機会が増えて、RailsのActionCableみたいなことがLaravelのEcho(ブロードキャスト 6.x Laravel)で実現できるらしいと興味を持ったので試してみた。
だいたい下記記事の通りだけど、一部記載の通りでは動作しなかったところもあるので捕捉的にで実現できるらしいと興味を持ったので試してみた。
だいたい下記記事の通りだけど、一部記載の通りでは動作しなかったり躓いたところもあるので捕捉として、Laravel初心者なので環境の構築からメモを残す。お試しのVbox上構築なので、セキュリティ対策とかそんな吟味してないので気を付けて!
長いのでまとめると
- チャンネル購読するにはクライアント側でチャンネル名にRedisのprefix(laravel_database_)を足す必要があった。
- ポート開放(firewall-cmd)忘れずに。
- laravel-echo-server start でエラーでたら下記コマンドで直った。
sudo npm install n -g
sudo n latest
環境
- CentOS 7
- VirtualBox ネットワークはブリッジアダプタ(ipは 192.168.0.100 とする)
- PHP 7.3
- Laravel Framework 6.6.0
- Apache/2.4.6
- mariadb-server
- Redis
「larapro」が今回のテスト用のlaravelプロジェクト名です
ユーザー名は「centuser」ということにします。
構築
sudo yum install epel-release
sudo rpm -ivh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
sudo yum -y install --enablerepo=remi,remi-php73 php php-devel php-mbstring php-pdo php-gd php-xml php-mcrypt
sudo yum -y install --enablerepo=remi,remi-php73 php-opcache php-mysqlnd
sudo yum -y install --enablerepo=remi,remi-php73 composer
sudo yum -y install --enablerepo=remi,remi-php73 php-pecl-redis
DB周り
sudo yum install mariadb mariadb-server mariadb-client
sudo vi /etc/my.cnf
[client]
default-character-set=utf8mb4[mysql]
default-character-set=utf8mb4[mysqldump]
default-character-set=utf8mb4[mysqld]
character-set-server=utf8mb4
sudo systemctl start mariadb
sudo systemctl enable mariadb
sudo mysql_secure_installation
mysql -u root -p
文字コードの確認 UTF8mb4になってればOK
MariaDB [(none)]> show variables like '%char%';
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | utf8mb4 |
| character_set_connection | utf8mb4 |
| character_set_database | utf8mb4 |
| character_set_filesystem | binary |
| character_set_results | utf8mb4 |
| character_set_server | utf8mb4 |
| character_set_system | utf8 |
- | character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
適当にデータベースを用意する
MariaDB [(none)]> CREATE DATABASE test_laravel;
Apache httpd周り
sudo mkdir /var/www/project
sudo chmod 2775 /var/www/project/
sudo chown apache:apache /var/www/project/
sudo usermod -aG apache centuser
sudo vi /etc/httpd/conf/httpd.conf
Vbox上でIPアクセスするのでバーチャルホストではなくDocuRoot直接設定しちゃう
DocumentRoot "/var/www/project/larapro/public"
<Directory "/var/www">
AllowOverride None
Require all granted
</Directory>
<Directory "/var/www/project">
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
sudo systemctl restart httpd
sudo systemctl enable httpd
Redis
sudo yum install redis
sudo systemctl enable redis
sudo systemctl start redis
redis-cli
Firewall ポート開放
sudo firewall-cmd --add-service=http --permanent
sudo firewall-cmd --add-port=6001/tcp --permanent
sudo firewall-cmd --reload
Laravel構築
cd /var/www/project/
composer create-project --prefer-dist laravel/laravel larapro
cd larapro
npm install --save laravel-echo socket.io-client
composer require predis/predis
npm install -g laravel-echo-server
laravel-echo-server init
こんな感じで対話形式でLaravel Echoの設定する
192.168.0.100 のところは各々の環境のアドレスを設定してください
? Do you want to run this server in development mode? Yes
? Which port would you like to serve from? 6001
? Which database would you like to use to store presence channel members? redis
? Enter the host of your Laravel authentication server. http://192.168.0.100
? Will you be serving on http or https? http
? Do you want to generate a client ID/Key for HTTP API? Yes
? Do you want to setup cross domain access to the API? Yes
? Specify the URI that may access the API: http://192.168.0.100:80
? Enter the HTTP methods that are allowed for CORS: GET, POST
? Enter the HTTP headers that are allowed for CORS: Origin, Content-Type, X-Auth-Token, X-Requested-With, Accept, Authorizat
ion, X-CSRF-TOKEN, X-Socket-Id
? What do you want this config to be saved as? laravel-echo-server.json
appId: xxxxxxxxxxxxxxxx
key: 01010101010101010101010101010101
Configuration file saved. Run laravel-echo-server start to run server.
sudo laravel-echo-server start
※もし
Starting server in DEV mode...
/usr/lib/node_modules/laravel-echo-server/node_modules/ws/lib/websocket.js:347
...options
^^^
というエラーがでたら
sudo npm install n -g
sudo n latest
を実行しよう
ここから先はだいたい参考記事(https://qiita.com/zaburo/items/34289d4573f39113b25a)と同じ
ディレクトリは引き続きプロジェクトルート(/var/www/project/larapro)にて
vi config/app.php
vi .env
php artisan make:event PublicEvent
vi ./app/Events/PublicEvent.php
<?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 PublicEvent implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;/**
* Create a new event instance.
*
* @return void
*/
public function __construct()
{
//
}/**
* Get the channels the event should broadcast on.
*
* @return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
return new Channel('hoge-channel');
// return new PrivateChannel('channel-name');
}
public function broadcastWith()
{
return [
'message' => 'PUBLIC',
];
}
}
vi ./routes/web.php
ここでは「/fire」にアクセスしたらEvent発火させることにした
Route::get('/', function () {
return view('welcome');
});Route::get('/fire', function(){
broadcast(new \App\Events\PublicEvent);
return 'public';
});
vi ./resources/js/bootstrap.js
ファイル末尾に下記を挿入
import Echo from 'laravel-echo';
window.io = require('socket.io-client');//接続情報
window.Echo = new Echo({
broadcaster: 'socket.io',
host: window.location.hostname + ':6001'
});//購読するチャネルの設定
window.Echo.channel('laravel_database_hoge-channel')
.listen('PublicEvent', (e) => {
console.log(e);
});
※余談ハマった点
window.Echo.channel('laravel_database_hoge-channel')
購読チャンネル名は「hoge-channel」だが、それに加えて「laravel_database」をprefixとして頭に付け加えなければならなかった。
prefixがどこで設定されているかというと「./config/database.php」のこのあたり
'redis' => [
'client' => env('REDIS_CLIENT', 'phpredis'),
'options' => [
'cluster' => env('REDIS_CLUSTER', 'redis'),
'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'),
],
npm run dev
vi ./resources/views/welcome.blade.php
<head>内に挿入
<body>タグ最後に挿入
<script src="{{ asset('js/app.js')}}"></script>
あとは参考記事(https://qiita.com/zaburo/items/34289d4573f39113b25a)と同じように、「http://192.168.0.100/」でコンソールを開いておいて「http://192.168.0.100/fire」を開いたらコンソールにPUBLICと表示されたら成功
おしまい
プライベートチャンネルは必要になったらまた試すかも
でもあとは参考記事と同じで大丈夫だと思う
重ねて感謝