SlideShare a Scribd company logo
1 of 22
サーバーを作ろう PHP でやるお(^ω^)
目次 勉強しよう TCP/IP Socket API クライアントとサーバー 設計しよう サーバーの多重化 ウェブプログラマが何故サーバーを作るの?
TCP/IP ストリーム型の通信プロトコル 送ったら、送った順に届く 順序を持った可変長バイト列(文字列に変換しやすい!)として送ったり、受け取ったりできるのでプログラミングしやすい ちゃんと届けられる 相手が通信可能な状態かどうか分かる 「相手が通信可能な状態じゃなかったら」という処理を書ける 届いたかどうか分かる 「届かなかったら」という処理を書ける
TCP/IP 送ったら送った順に届く $fp = stream_socket_client('tcp://www.nicovideo.jp:80'); fwrite($fp, "GET / HTTP/1.0"); fwrite($fp, "Host: www.nicovideo.jp"); echo stream_get_contents($fp); fclose($fp);
送ったら送った順に届く HTML がそのまま読めるよ www.nicovideo.jp 送ったら 送った順に届く PHP Web Server HTTP/1.1 200 OK <html>…</html> HTTP/1.1 200 OK <html>…</html> TCP/IP TCP/IP
TCP/IP ちゃんと届けられる $fp = stream_socket_client('tcp://www.nicovideo.jp:80', $errno, $errstr); if ($fp=== false) {  throw new Exception($errstr); } if (fwrite($fp, "GET / HTTP/1.0") === false) {   throw new Exception($php_errormsg); } if (fwrite($fp, "Host: www.nicovideo.jp") === false) {  throw new Exception($php_errormsg); } echo stream_get_contents($fp); fclose($fp);
ちゃんと届けられる ちゃんと届いてるみたいだな www.nicovideo.jp PHP Web Server GET / HTTP/1.0 Host: www.nicovideo.jp GET / HTTP/1.0 Host: www.nicovideo.jp TCP/IP TCP/IP 届いた 届いた
TCP/IP 考えてみよう ストリーム型じゃない通信プロトコルってどんなのだろう TCP/IP 以外のストリーム型通信プロトコルを考えてみよう
Socket API TCP/IP などで通信相手と接続するためのライブラリが socket 接続後は、ファイルに対する読み書きの関数がそのまま使える
ファイル操作の関数が使える ソケットから読む ファイルから読む $fp = stream_socket_client(              'tcp://www.nicovideo.jp:80'); fwrite($fp, "GET / HTTP/1.0"); fwrite($fp, "Host: www.nicovideo.jp"); while (fgets($fp) !== "") { } $content = stream_get_contents($fp); if (!mb_check_encoding($content, 'UTF-8')) {   throw new Exception('Invalid encoding!'); } fclose($fp); libxml_use_internal_errors(true); $doc = new DOMDocument(); $doc->loadHTML($content); libxml_clear_errors(); echo $doc->getElementsByTagName('title')       ->item(0)->textContent; $fp = fopen('test.html', 'r'); $content = stream_get_contents($fp); if (!mb_check_encoding($content, 'UTF-8')) {   throw new Exception('Invalid encoding!'); } fclose($fp); libxml_use_internal_errors(true); $doc = new DOMDocument(); $doc->loadHTML($content); libxml_clear_errors(); echo $doc->getElementsByTagName('title')       ->item(0)->textContent; まったく同じコードを使える
Socket API 考えてみよう なんで、通信なのにファイルで抽象化してるんだろう?
クライアントとサーバー 接続する側をクライアントと言う 接続を待つ側をサーバーと言う それぞれで、接続が確立するまでのコードが違う
作ってみよう Mecabで形態素解析して、結果を返すサーバーと、そのクライアントを作る Mecabのインストール sudoapt-get install mecab # mecabプログラム sudoapt-get install libmecab-dev # mecab.so を作るのに必要 sudoapt-get install mecab-naist-jdic mecab-jumandic-utf8 # mecabの UTF-8 の辞書 sudoapt-get install build-essentials # php拡張をコンパイルするためのツール群 sudopear channel-discover pecl.opendogs.org sudopear remote-list -c opendogs sudopear install opendogs/mecab-beta # 以下のファイルに extension=mecab.so を追加 sudovim /etc/php5/cli/php.ini
クライアント側のコード 繋ぐだけ エラー処理とかは各自勉強してね $fp = stream_socket_client('tcp://127.0.0.1:1111'); fwrite($fp, json_encode($argv[1]) . ""); $list = json_decode(fgets($fp, 1024)); var_dump($list); fclose($fp);
サーバー側のコード 接続を待って、 接続を確立する エラー処理とかは各自勉強してね $server = stream_socket_server('tcp://127.0.0.1:1111'); while (true) {   $fp = stream_socket_accept($server);   while (!feof($fp)) {     $str = fgets($fp, 1024); fwrite($fp, json_encode(mecab_split(json_decode($str))) . "");   } fclose($fp); } fclose($server);
サーバー側の処理の多重化 前の例では、サーバー側のコードは、常に一つのクライアントに対しての処理しかしない 複数のクライアントに対して処理をしたい場合は、以下のいずれかの方法でサーバーの処理を多重化する必要がある フォークによる多重化 イベントループによる多重化 スレッドによる多重化
フォークによる多重化 プロセスを分身させる。 メモリは COW で節約されるけど、スレッドと比べてメモリを食う 処理ごとに値が独立してるので、プログラミングが楽 $server = stream_socket_server('tcp://127.0.0.1:1111'); while (true) {   $fp = stream_socket_accept($server);   if (!pcntl_fork()) {     while (!feof($fp)) {       $str = fgets($fp, 1024); fwrite($fp, json_encode(mecab_split(json_decode($str))) . "");     } fclose($fp);     exit;  } } fclose($server);
スレッドによる多重化 PHP では出来ない?? フォークするより、省メモリ。 とはいえ、スタック領域などのメモリは食う。 マルチスレッドプログラミング難しい><
イベントループによる多重化 フォークや、スレッドと比べて軽量 $server = stream_socket_server('tcp://127.0.0.1:1111'); stream_set_blocking($server, 0); $base = event_base_new(); $event = event_new(); event_set($event, $server, EV_READ | EV_PERSIST, 'ev_accept', $base); event_base_set($event, $base); event_add($event); event_base_loop($base); $id = 0; $fps = array(); $bufs = array();
イベントループによる多重化 function ev_accept($server, $flag, $base) {   global $id;   global $fps;   global $bufs;   $fp = stream_socket_accept($server); stream_set_blocking($fp, 0);   $id++;   $buf = event_buffer_new($fp, 'ev_read', NULL, 'ev_error', $id); event_buffer_base_set($buf, $base); event_buffer_timeout_set($buf, 30, 30); event_buffer_watermark_set($buf, EV_READ, 0, 0xffffff); event_buffer_priority_set($buf, 10); event_buffer_enable($buf, EV_READ | EV_PERSIST);   $fps[$id] = $fp;   $bufs[$id] = $buf; }
イベントループによる多重化 function ev_error($buf, $error, $id) {   global $id;   global $fps;   global $bufs; event_buffer_disable($bufs[$id], EV_READ | EV_WRITE); event_buffer_free($bufs[$id]); fclose($fps[$id]);   unset($fps[$id], $bufs[$id]); } function ev_read($buf, $id) {   global $id;   global $fps;   global $bufs;   while ($str = event_buffer_read($buf, 1024)) {     $fp = $fps[$id]; fwrite($fp, json_encode(mecab_split(json_decode($str))) . "");   } }
ウェブプログラマが何故サーバーを作るの? プロセスやマシンに縛られるのはやめよう 1プロセスに拘らなくなる プログラミング言語に拘らなくてよくなる 使いたいライブラリがあったら、なんでも使える。ソケットでプロセスを繋げばいい 1マシンに拘らなくなる OS に拘らなくてもよくなる 負荷分散も自由自在

More Related Content

What's hot

2020 acl learning_to_recover_from_multi-modality_errors_for_non-autoregressiv...
2020 acl learning_to_recover_from_multi-modality_errors_for_non-autoregressiv...2020 acl learning_to_recover_from_multi-modality_errors_for_non-autoregressiv...
2020 acl learning_to_recover_from_multi-modality_errors_for_non-autoregressiv...広樹 本間
 
Perl and Email #3 ``Haineko''/Kyoto.pm #5
Perl and Email #3 ``Haineko''/Kyoto.pm #5Perl and Email #3 ``Haineko''/Kyoto.pm #5
Perl and Email #3 ``Haineko''/Kyoto.pm #5azumakuniyuki 🐈
 
Message delivery over XMPP network
Message delivery over XMPP networkMessage delivery over XMPP network
Message delivery over XMPP networkHideki Saito
 
サーバー実装いろいろ
サーバー実装いろいろサーバー実装いろいろ
サーバー実装いろいろkjwtnb
 
JVM-Reading-ConcurrentMarkSweep
JVM-Reading-ConcurrentMarkSweepJVM-Reading-ConcurrentMarkSweep
JVM-Reading-ConcurrentMarkSweepMinoru Nakamura
 
JSONでメール送信 | HTTP API Server ``Haineko''/YAPC::Asia Tokyo 2013 LT Day2
JSONでメール送信 | HTTP API Server ``Haineko''/YAPC::Asia Tokyo 2013 LT Day2JSONでメール送信 | HTTP API Server ``Haineko''/YAPC::Asia Tokyo 2013 LT Day2
JSONでメール送信 | HTTP API Server ``Haineko''/YAPC::Asia Tokyo 2013 LT Day2azumakuniyuki 🐈
 
20131208 agile samuraibasecamp
20131208 agile samuraibasecamp20131208 agile samuraibasecamp
20131208 agile samuraibasecampHiroshi SHIBATA
 
SPDY/3 の HTTP 重畳効果を測定する
SPDY/3 の HTTP 重畳効果を測定するSPDY/3 の HTTP 重畳効果を測定する
SPDY/3 の HTTP 重畳効果を測定する彰 村地
 
H2O - making HTTP better
H2O - making HTTP betterH2O - making HTTP better
H2O - making HTTP betterKazuho Oku
 
Chef の気まぐれ環境構築 〜季節の Capistrano を添えて〜 #jawsug
Chef の気まぐれ環境構築 〜季節の Capistrano を添えて〜 #jawsugChef の気まぐれ環境構築 〜季節の Capistrano を添えて〜 #jawsug
Chef の気まぐれ環境構築 〜季節の Capistrano を添えて〜 #jawsugTakeshi Komiya
 
Gunosy.go#2 package/compress
Gunosy.go#2 package/compressGunosy.go#2 package/compress
Gunosy.go#2 package/compressShunsuke Aihara
 
Perl and Email #2/Kansai.pm第14回ミーティング@京都
Perl and Email #2/Kansai.pm第14回ミーティング@京都Perl and Email #2/Kansai.pm第14回ミーティング@京都
Perl and Email #2/Kansai.pm第14回ミーティング@京都azumakuniyuki 🐈
 
PowerShell 紹介
PowerShell 紹介PowerShell 紹介
PowerShell 紹介tsudaa
 
Janogia20120921 yoshinotakeshi
Janogia20120921 yoshinotakeshiJanogia20120921 yoshinotakeshi
Janogia20120921 yoshinotakeshiKeisuke Ishibashi
 
Measurement of Maximum new NAT-sessions per second / How to send packets
Measurement of Maximum new NAT-sessionsper second / How to send packetsMeasurement of Maximum new NAT-sessionsper second / How to send packets
Measurement of Maximum new NAT-sessions per second / How to send packets@ otsuka752
 

What's hot (20)

Varnish
VarnishVarnish
Varnish
 
ゆるかわPhp
ゆるかわPhpゆるかわPhp
ゆるかわPhp
 
2020 acl learning_to_recover_from_multi-modality_errors_for_non-autoregressiv...
2020 acl learning_to_recover_from_multi-modality_errors_for_non-autoregressiv...2020 acl learning_to_recover_from_multi-modality_errors_for_non-autoregressiv...
2020 acl learning_to_recover_from_multi-modality_errors_for_non-autoregressiv...
 
Perl and Email #3 ``Haineko''/Kyoto.pm #5
Perl and Email #3 ``Haineko''/Kyoto.pm #5Perl and Email #3 ``Haineko''/Kyoto.pm #5
Perl and Email #3 ``Haineko''/Kyoto.pm #5
 
Message delivery over XMPP network
Message delivery over XMPP networkMessage delivery over XMPP network
Message delivery over XMPP network
 
サーバー実装いろいろ
サーバー実装いろいろサーバー実装いろいろ
サーバー実装いろいろ
 
JVM-Reading-ConcurrentMarkSweep
JVM-Reading-ConcurrentMarkSweepJVM-Reading-ConcurrentMarkSweep
JVM-Reading-ConcurrentMarkSweep
 
JSONでメール送信 | HTTP API Server ``Haineko''/YAPC::Asia Tokyo 2013 LT Day2
JSONでメール送信 | HTTP API Server ``Haineko''/YAPC::Asia Tokyo 2013 LT Day2JSONでメール送信 | HTTP API Server ``Haineko''/YAPC::Asia Tokyo 2013 LT Day2
JSONでメール送信 | HTTP API Server ``Haineko''/YAPC::Asia Tokyo 2013 LT Day2
 
Introduction pp.js
Introduction pp.jsIntroduction pp.js
Introduction pp.js
 
NanoStrand
NanoStrandNanoStrand
NanoStrand
 
20131208 agile samuraibasecamp
20131208 agile samuraibasecamp20131208 agile samuraibasecamp
20131208 agile samuraibasecamp
 
SPDY/3 の HTTP 重畳効果を測定する
SPDY/3 の HTTP 重畳効果を測定するSPDY/3 の HTTP 重畳効果を測定する
SPDY/3 の HTTP 重畳効果を測定する
 
H2O - making HTTP better
H2O - making HTTP betterH2O - making HTTP better
H2O - making HTTP better
 
Em synchrony について
Em synchrony についてEm synchrony について
Em synchrony について
 
Chef の気まぐれ環境構築 〜季節の Capistrano を添えて〜 #jawsug
Chef の気まぐれ環境構築 〜季節の Capistrano を添えて〜 #jawsugChef の気まぐれ環境構築 〜季節の Capistrano を添えて〜 #jawsug
Chef の気まぐれ環境構築 〜季節の Capistrano を添えて〜 #jawsug
 
Gunosy.go#2 package/compress
Gunosy.go#2 package/compressGunosy.go#2 package/compress
Gunosy.go#2 package/compress
 
Perl and Email #2/Kansai.pm第14回ミーティング@京都
Perl and Email #2/Kansai.pm第14回ミーティング@京都Perl and Email #2/Kansai.pm第14回ミーティング@京都
Perl and Email #2/Kansai.pm第14回ミーティング@京都
 
PowerShell 紹介
PowerShell 紹介PowerShell 紹介
PowerShell 紹介
 
Janogia20120921 yoshinotakeshi
Janogia20120921 yoshinotakeshiJanogia20120921 yoshinotakeshi
Janogia20120921 yoshinotakeshi
 
Measurement of Maximum new NAT-sessions per second / How to send packets
Measurement of Maximum new NAT-sessionsper second / How to send packetsMeasurement of Maximum new NAT-sessionsper second / How to send packets
Measurement of Maximum new NAT-sessions per second / How to send packets
 

Similar to サーバーを作ろう (毎週のハンズオン勉強会の資料)

about Thrift
about Thriftabout Thrift
about ThriftNaoya Ito
 
Abコマンドを使ったウェブアプリケーションのパフォーマンス計測
Abコマンドを使ったウェブアプリケーションのパフォーマンス計測Abコマンドを使ったウェブアプリケーションのパフォーマンス計測
Abコマンドを使ったウェブアプリケーションのパフォーマンス計測Hidenori Goto
 
これからのアプリ開発はIPv6対応で行こう!(2014/09/20 OSC Hiroshima版)
これからのアプリ開発はIPv6対応で行こう!(2014/09/20 OSC Hiroshima版)これからのアプリ開発はIPv6対応で行こう!(2014/09/20 OSC Hiroshima版)
これからのアプリ開発はIPv6対応で行こう!(2014/09/20 OSC Hiroshima版)v6app
 
Dockerを使ったローカルでの開発から本番環境へのデプロイまで
Dockerを使ったローカルでの開発から本番環境へのデプロイまでDockerを使ったローカルでの開発から本番環境へのデプロイまで
Dockerを使ったローカルでの開発から本番環境へのデプロイまでRyo Nakamaru
 
泥臭い運用から、プログラマブルインフラ構築(に行きたい)
泥臭い運用から、プログラマブルインフラ構築(に行きたい) 泥臭い運用から、プログラマブルインフラ構築(に行きたい)
泥臭い運用から、プログラマブルインフラ構築(に行きたい) Akihiro Kuwano
 
ゲームのインフラをAwsで実戦tips全て見せます
ゲームのインフラをAwsで実戦tips全て見せますゲームのインフラをAwsで実戦tips全て見せます
ゲームのインフラをAwsで実戦tips全て見せますinfinite_loop
 
Railsの運用について
Railsの運用についてRailsの運用について
Railsの運用についてYuuki Namikawa
 
Html5, Web Applications 2
Html5, Web Applications 2Html5, Web Applications 2
Html5, Web Applications 2totty jp
 
2012 osc北海道 セッション資料「blackjumbodog利用のすすめ」
2012 osc北海道 セッション資料「blackjumbodog利用のすすめ」2012 osc北海道 セッション資料「blackjumbodog利用のすすめ」
2012 osc北海道 セッション資料「blackjumbodog利用のすすめ」Shinichi Hirauchi
 
Erlangご紹介 websocket編
Erlangご紹介 websocket編Erlangご紹介 websocket編
Erlangご紹介 websocket編Masatoshi Itoh
 
Couch DB in 15minutes
Couch DB in 15minutesCouch DB in 15minutes
Couch DB in 15minutesYohei Sasaki
 
Qlik TechFest C-5 Qlikエンジンのサーバーサイド拡張(SSE)の 基礎から実装まで
Qlik TechFest C-5  Qlikエンジンのサーバーサイド拡張(SSE)の 基礎から実装までQlik TechFest C-5  Qlikエンジンのサーバーサイド拡張(SSE)の 基礎から実装まで
Qlik TechFest C-5 Qlikエンジンのサーバーサイド拡張(SSE)の 基礎から実装までQlikPresalesJapan
 
FD.io VPP事始め
FD.io VPP事始めFD.io VPP事始め
FD.io VPP事始めtetsusat
 
PHP、おまえだったのか。 いつもHTTPメッセージを 運んでくれたのは。
PHP、おまえだったのか。 いつもHTTPメッセージを 運んでくれたのは。PHP、おまえだったのか。 いつもHTTPメッセージを 運んでくれたのは。
PHP、おまえだったのか。 いつもHTTPメッセージを 運んでくれたのは。sasezaki
 
Inside mobage platform
Inside mobage platformInside mobage platform
Inside mobage platformToru Yamaguchi
 

Similar to サーバーを作ろう (毎週のハンズオン勉強会の資料) (20)

about Thrift
about Thriftabout Thrift
about Thrift
 
Abコマンドを使ったウェブアプリケーションのパフォーマンス計測
Abコマンドを使ったウェブアプリケーションのパフォーマンス計測Abコマンドを使ったウェブアプリケーションのパフォーマンス計測
Abコマンドを使ったウェブアプリケーションのパフォーマンス計測
 
これからのアプリ開発はIPv6対応で行こう!(2014/09/20 OSC Hiroshima版)
これからのアプリ開発はIPv6対応で行こう!(2014/09/20 OSC Hiroshima版)これからのアプリ開発はIPv6対応で行こう!(2014/09/20 OSC Hiroshima版)
これからのアプリ開発はIPv6対応で行こう!(2014/09/20 OSC Hiroshima版)
 
勉強会資料①
勉強会資料①勉強会資料①
勉強会資料①
 
Dockerを使ったローカルでの開発から本番環境へのデプロイまで
Dockerを使ったローカルでの開発から本番環境へのデプロイまでDockerを使ったローカルでの開発から本番環境へのデプロイまで
Dockerを使ったローカルでの開発から本番環境へのデプロイまで
 
泥臭い運用から、プログラマブルインフラ構築(に行きたい)
泥臭い運用から、プログラマブルインフラ構築(に行きたい) 泥臭い運用から、プログラマブルインフラ構築(に行きたい)
泥臭い運用から、プログラマブルインフラ構築(に行きたい)
 
ゲームのインフラをAwsで実戦tips全て見せます
ゲームのインフラをAwsで実戦tips全て見せますゲームのインフラをAwsで実戦tips全て見せます
ゲームのインフラをAwsで実戦tips全て見せます
 
Clrh 110716 wcfwf
Clrh 110716 wcfwfClrh 110716 wcfwf
Clrh 110716 wcfwf
 
Railsの運用について
Railsの運用についてRailsの運用について
Railsの運用について
 
Html5, Web Applications 2
Html5, Web Applications 2Html5, Web Applications 2
Html5, Web Applications 2
 
PHP on Cloud
PHP on CloudPHP on Cloud
PHP on Cloud
 
Fluentd meetup #2
Fluentd meetup #2Fluentd meetup #2
Fluentd meetup #2
 
2012 osc北海道 セッション資料「blackjumbodog利用のすすめ」
2012 osc北海道 セッション資料「blackjumbodog利用のすすめ」2012 osc北海道 セッション資料「blackjumbodog利用のすすめ」
2012 osc北海道 セッション資料「blackjumbodog利用のすすめ」
 
Erlangご紹介 websocket編
Erlangご紹介 websocket編Erlangご紹介 websocket編
Erlangご紹介 websocket編
 
[Japan Tech summit 2017] DEP 005
[Japan Tech summit 2017] DEP 005[Japan Tech summit 2017] DEP 005
[Japan Tech summit 2017] DEP 005
 
Couch DB in 15minutes
Couch DB in 15minutesCouch DB in 15minutes
Couch DB in 15minutes
 
Qlik TechFest C-5 Qlikエンジンのサーバーサイド拡張(SSE)の 基礎から実装まで
Qlik TechFest C-5  Qlikエンジンのサーバーサイド拡張(SSE)の 基礎から実装までQlik TechFest C-5  Qlikエンジンのサーバーサイド拡張(SSE)の 基礎から実装まで
Qlik TechFest C-5 Qlikエンジンのサーバーサイド拡張(SSE)の 基礎から実装まで
 
FD.io VPP事始め
FD.io VPP事始めFD.io VPP事始め
FD.io VPP事始め
 
PHP、おまえだったのか。 いつもHTTPメッセージを 運んでくれたのは。
PHP、おまえだったのか。 いつもHTTPメッセージを 運んでくれたのは。PHP、おまえだったのか。 いつもHTTPメッセージを 運んでくれたのは。
PHP、おまえだったのか。 いつもHTTPメッセージを 運んでくれたのは。
 
Inside mobage platform
Inside mobage platformInside mobage platform
Inside mobage platform
 

サーバーを作ろう (毎週のハンズオン勉強会の資料)