Edited at
LaravelDay 21

laravel4+redis pub/sub

More than 5 years have passed since last update.

今回は、laravel4とredisの機能であるpub/subを組み合わせた実装方法を紹介します。

laravel4というか、どちらかというとredis寄りのものですが・・。

php(Laravel)でのsubscribe受信方法は別で紹介しています。そちらも合わせてご覧下さい

Laravel webscoket(push & pubsub) 後編


pub/sub

redisはmemcache以上の働きをするので、

session, cache以外にnosqlとして重宝してる方も多いのではないでしょうか?

自分も個人の開発で多用したり、会社でも好んで使ったりしています。

websocketと言えばデータストアはredis!といっても良いくらいなんですが、

それにはレスポンスが早いなどももちろんですが、

複数台のwebsocketサーバからmysqlなどのデータベースにつないだ場合、

サーバ01がinsertした後に取得はできますが、

サーバ02はinsertされた事を知る術がありません。

実際にはinsertしたよ!という情報を01から02へサーバ間でsocketでつないで、

通知して云々という方法でしょうか?

厄介!

そこで、redisのpub/subという機能を使用します。

この機能は何かと言いますと、publisherとsubscriberの関係をredisで管理でき、

早い話、redisに接続してる他のものに対して通知ができます。

いちいち情報を取得しにいかなくても送ってくれるというありがたい機能です。

そんな機能をlaravel4で使ってみます。

といっても実装自体はものすごく簡単です。

まず必要なものをインストールします。

といってもlaravel4でも使っているpredisのasyncというものを使います。


hiredis

hiredes

Cのredisクライアントで、predis-asyncがラッパーしてるそうな

git clone git://github.com/redis/hiredis.git

cd hiredis
make && make install


predis-async

predis-async

composerでいつも通りです。


では、実装!


app/commands/RedisAsyncCommand.php

use Illuminate\Console\Command;

use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;

class RedisAsyncCommand extends Command {

/**
* @var string
*/

protected $name = 'redis:async';

/**
* @var string
*/

protected $description = "redis async start";

/**
* @return void
*/

public function fire()
{
// 接続先
$client = new Predis\Async\Client('tcp://127.0.0.1:6379');

$client->connect(function ($client) {
echo "redis async start!\n";

$logger = new Predis\Async\Client('tcp://127.0.0.1:6379', $client->getEventLoop());
// subscriber チャンネルに登録します
$client->pubsub('subscriber', function ($event) use ($logger) {
// 受信したメッセージをlistにpush
$logger->rpush("{$event->channel}", $event->payload, function () use ($event) {
echo "Stored message `{$event->payload}` from {$event->channel}.\n";
});
});
});
$this->info('connected!');
$client->getEventLoop()->run();
}
}


実際にはasync用にfacadeを作って実装した方が綺麗でしょう!

facadeの作り方

predis-asyncのサンプルまんまですね!

redisの subscriberというチャンネルに登録させます(チャンネル名は適当にどうぞ)

受信したデータはredisに保存される訳ではないので、

とりあえずlistに突っ込んでます。

artisanに登録を忘れずに


app/start/artisan.php

Artisan::add(new RedisAsyncCommand);


artisanで待機状態にさせます


artisanコマンド

php artisan redis:async

connected!
redis async start!

これで待機状態になりました。

では試しにredisからsubscriberチャンネルに大して通知してみます。


redis-cli

> publish subscriber 'Hello!'

(integer) 1

成功したようです。

起動させた待機状態のphpは・・・

Stored message `Hello!` from subscriber.

しっかりと通知を受信する事ができました。

これを元にwebsocketを使用したアプリケーションを作っていけば面白いものができると思います。

pushの実装方法も紹介しましたので、

両方組み合わせて開発をするとモテるかもしれません

新しい技術にも難なく対応できるlaravel4のポテンシャルの高さは凄まじい!(fuelでも同じ事できますが)

明日は@kurikazu さんの簡単デプロイの話 です