laravel websocket(use redis pubsub) [laravel meetup tokyo]

25
laravel + websocket + Redis Laravel Meetup Tokyo JP Vol.3 2014/04/05 yuuki.takezawa

Upload: yuuki-takezawa

Post on 15-Jan-2015

2.192 views

Category:

Technology


8 download

DESCRIPTION

laravel meetup tokyo Vol.3 発表のスライドです。 laravelを使ったwebsocket実装でredisのpubsubを用いた内容です sample code https://github.com/ytake/laravel-websocket

TRANSCRIPT

Page 1: laravel websocket(use redis pubsub) [Laravel meetup tokyo]

laravel + websocket + RedisLaravel Meetup Tokyo JP Vol.3 2014/04/05

yuuki.takezawa

Page 2: laravel websocket(use redis pubsub) [Laravel meetup tokyo]

PROFILE

yuuki takezawa social

github (https://github.com/ytake) facebook (https://www.facebook.com/yuuki.takezawa)

qiita (http://qiita.com/ytake) twitter(https://twitter.com/ex_takezawa)

!ベンチャー、フリー、現

php node.js RDBMS NoSQL !

Page 3: laravel websocket(use redis pubsub) [Laravel meetup tokyo]

sample code

本発表と対応したサンプルは下記になります https://github.com/ytake/laravel-websocket

!

Page 4: laravel websocket(use redis pubsub) [Laravel meetup tokyo]

laravelってどんなの?

良い意味でとにかく話題が多い => 注目度高い? illuminateコンポーネントの手軽さ container, databaseおすすめです

redis好きにはたまらない親和性(個人的な意見) 簡単に書くこともできて、がっちり堅実派にもおすすめ(間口が広い)

codeigniter系とはまたちょっと違う

Page 5: laravel websocket(use redis pubsub) [Laravel meetup tokyo]

Laravelを使ってみた感想 Why i chose Laravel?

新しいフレームワークを探していたときにたまたま見つけた laravel歴 1年

メインで使っていて、もう手放せないくらい それまでのphpと違う記述方法にほれた

DIがとにかくシンプルかつ強力 世界とつながる強力なコミュニティ

新技術対応がスムーズ(粗結合且つシンプルさ故に) MVCだけどそうじゃない自由さ(delete model!)

Page 6: laravel websocket(use redis pubsub) [Laravel meetup tokyo]

Laravel ちょっとあれなところ

他のフレームワークを使う時に書き方を忘れる 大規模になるとRouterがデカい IDEヘルパー必須(補完が効かない) Symfony\Componentべったり

Page 7: laravel websocket(use redis pubsub) [Laravel meetup tokyo]

attention!

require mcrypt!! router 記述 (don’t forget)

chmod -R 777 app/storage composerになれていない方はこれを機に慣れましょう

Better get used to composer

Page 8: laravel websocket(use redis pubsub) [Laravel meetup tokyo]

websocket

Page 9: laravel websocket(use redis pubsub) [Laravel meetup tokyo]

What is web socket?

双方向通信規格 お互いが情報発信源

持続した接続 リアルタイム性

チャット、お絵描き共有、ブラウザゲームなど 仲間はAjax long polling、HTTP Polling、Silverlightなど

モダンブラウザ以外は非対応

Page 10: laravel websocket(use redis pubsub) [Laravel meetup tokyo]

一般的なHTTP通信(イメージ)

requestがあってresponseがあります !

Page 11: laravel websocket(use redis pubsub) [Laravel meetup tokyo]

websocket(イメージ)

サーバからの一方的なrequestも可能になりました !

Page 12: laravel websocket(use redis pubsub) [Laravel meetup tokyo]

websocket 複数台あるけど 同期どうやるの?

Page 13: laravel websocket(use redis pubsub) [Laravel meetup tokyo]
Page 14: laravel websocket(use redis pubsub) [Laravel meetup tokyo]

What is Redis?

NoSQLという分類に入るインメモリ KVS (RDBMSはもういらない という意味じゃありません)

データの永続性(再起動してもデータあります) 早い、らくちん

(インメモリ故に低コストとは言いがたい) CPUの1コアを使う

イベントドリブンで即反応 スキーマなどはありません

memcachedのようにsession, cacheもおまかせ STRINGS, LISTS, SETS, HASHES, SORTED SETS

Page 15: laravel websocket(use redis pubsub) [Laravel meetup tokyo]

なぜRedisなのか

Page 16: laravel websocket(use redis pubsub) [Laravel meetup tokyo]

pubsubsubscriberへpublish

登録している全プロセスへ通知

Page 17: laravel websocket(use redis pubsub) [Laravel meetup tokyo]

実装

Page 18: laravel websocket(use redis pubsub) [Laravel meetup tokyo]

必要なもの

Redis zeromq php extension(PECL or build)

event extension(PECL) phpiredis extension(hiredis必要)

!React Ratchet

Predis\Async

Page 19: laravel websocket(use redis pubsub) [Laravel meetup tokyo]

つかったもの

Routing Controllers

Ioc Container(bind, make, service provider) Artisan CLI Model(Redis) Blade template

Page 20: laravel websocket(use redis pubsub) [Laravel meetup tokyo]

Modelmodel sample !class Datastore implements DatastoreInterface{ ! const KEY = "timeline:"; ! /** * @param array $array * @return mixed */ public function set(array $array) { return \Redis::connection()->rpush(self::KEY, json_encode($array)); } ! /** * @return \stdClass */ public function get() { $array = []; $result = \Redis::connection()->lrange(self::KEY, 0, -1); if(count($result)) { array_walk($result, function($value) use(&$array){ $array[] = json_decode($value); }); return $array; } return $result; } !

Page 21: laravel websocket(use redis pubsub) [Laravel meetup tokyo]

Controllercontroller sample interfaceをタイプヒンティング(redis以外の何かにするかもしれない!) ! protected $datastore; ! /** @param DatastoreInterface $datastore */ public function __construct(DatastoreInterface $datastore) { $this->datastore = $datastore; } ! public function index() { $view = \View::make('emit.index'); $view->with('list', $this->datastore->get()); return $view; } ! public function store() { if($this->datastore->publish( ['body' => \Input::get('body', null)])) { return \Response::json(['result' => true] ,200); } }

Page 22: laravel websocket(use redis pubsub) [Laravel meetup tokyo]

ServiceProviderServiceProvider sample app/config/app.php, app/config/{env}/app.phpに忘れずに追記します クラスとインターフェースの関係性を実装 CLIの追加は、ServiceProvider、またはstart/artisan.phpで追加可能です ! public function register() { $this->app->bind("Model\Interfaces\AsyncInterface", function(){ return new \Models\Redis\Async(new \ZMQContext()); }); ! $this->app->bind("Ratchet\Wamp\WampServerInterface", "Models\Websocket\Push"); ! $this->app->bind("pubsub.server", function() { return new \App\Commands\PubSubCommand( $this->app->make("Model\Interfaces\AsyncInterface"), $this->app->make("Ratchet\Wamp\WampServerInterface") ); }); $this->commands("pubsub.server"); } ! public function provides() { return ["pubsub.server"]; } !!

Page 23: laravel websocket(use redis pubsub) [Laravel meetup tokyo]

ArtisanArtisan sample 実装していきます (Symfony\Component\Console) ! public function __construct(AsyncInterface $loop, WampServerInterface $wamp) { parent::__construct(); $this->loop = $loop; $this->wamp = $wamp; } ! public function fire() { $loop = $this->loop->async(); $this->info('redis subscribe start'); ! $this->pull($loop, $this->wamp); ! $webSock = new \React\Socket\Server($loop); $webSock->listen($this->option('port'), '0.0.0.0'); ! $webServer = new \Ratchet\Server\IoServer( new \Ratchet\Http\HttpServer( new \Ratchet\WebSocket\WsServer( new \Ratchet\Wamp\WampServer($this->wamp) ) ), $webSock); ! $this->info('websocket server boot'); $this->comment('Listening on port ' . $this->option('port')); $loop->run(); }

Page 24: laravel websocket(use redis pubsub) [Laravel meetup tokyo]

Exception

app/start/global.php エラーをcatchして処理してくれます !<?php !App::error(function(\Symfony\Component\HttpKernel\Exception\NotFoundHttpException $exception, $code) { return \Response::make('not found', 404); }); !!App::error(function(\Predis\Connection\ConnectionException $exception, $code) { return "Redis {$exception->getMessage()}"; });

Page 25: laravel websocket(use redis pubsub) [Laravel meetup tokyo]

便利なものを作ったら パッケージとして公開しましょう!

!日本ではまだまだこれから