Slide 1

Slide 1 text

Copyright© M&Aクラウド PHPで WebSocketサーバーを実装しよう 2025 PHPConference 2025 / Kenjiro Kubota

Slide 2

Slide 2 text

Copyright© M&Aクラウド Profile 久保⽥ 賢⼆朗 kubotak-is kubotak_public kenjiro.kubota 株式会社M&Aクラウド所属 TypeScript PHP https://kubotak.page プロフェッショナルWebプログラミング Laravel (共著) 愛⽝:⾖柴 kubotak

Slide 3

Slide 3 text

Copyright© M&Aクラウド 今⽇話すこと、話さないこと ⭕ 話すこと ❌ 話さないこと ● ⼀般的なPHPアプリケーションとWebSocketサーバーの⼤まかな違い ● PHPでWebSocketサーバーを実装できるライブラリ‧ミドルウェアの紹介 ● それらのライブラリ‧ミドルウェアがどのようにノンブロッキング処理を扱ってい るのか ● 各ライブラリ‧ミドルウェアの詳細 ● WebSocketの実運⽤やセキュアに扱うこと

Slide 4

Slide 4 text

Copyright© M&Aクラウド そもそも、WebSocketってなに

Slide 5

Slide 5 text

Copyright© M&Aクラウド WebSocketとは RFC 6455(2011) The WebSocket Protocol 仕様 HTTPのリクエスト->レスポンス1往復という枠を超えて双⽅向‧常時接続をブラ ウザで実現するもの ⽬的 チャット‧ゲーム‧IoTテレメトリ‧共同編集など ユースケース

Slide 6

Slide 6 text

Copyright© M&Aクラウド WebSocketは ⼀般的なHTTP通信と何が違うのか

Slide 7

Slide 7 text

Copyright© M&Aクラウド PHPで⼀般的?といえば(コンテナ時代ではもう古いかもしれないが) Nginx+php_fpm

Slide 8

Slide 8 text

Copyright© M&Aクラウド PHPで⼀般的?といえば(コンテナ時代ではもう古いかもしれないが) Nginx+php_fpm レスポンスを返したら処理は終了する

Slide 9

Slide 9 text

Copyright© M&Aクラウド WebSocket

Slide 10

Slide 10 text

Copyright© M&Aクラウド WebSocket 接続確⽴後は双⽅向通信に切り替わる ので処理は継続する

Slide 11

Slide 11 text

Copyright© M&Aクラウド WebSocketサーバーを作る上での課題

Slide 12

Slide 12 text

Copyright© M&Aクラウド ⼀般的なWebサーバーでWebSocketサーバーを作る場合(概念) クライアントの数だけサーバープロセ スが必要になり、現実的ではない クライアント サーバープロセス クライアント サーバープロセス クライアント サーバープロセス

Slide 13

Slide 13 text

Copyright© M&Aクラウド WebSocketサーバーを実現するためにはノンブロッキングが重要 クライアント ノンブロッキング型 クライアント クライアント I/O待ちでワーカーを占有しない仕組みとして ノンブロッキング型が必要

Slide 14

Slide 14 text

Copyright© M&Aクラウド ノンブロッキングとは

Slide 15

Slide 15 text

Copyright© M&Aクラウド ブロッキング 処理1 HTTP API Call 処理2 Database 時間 前の処理が終わらないと次の処理を実⾏しな い、⼿続き型に実⾏されるプログラム

Slide 16

Slide 16 text

Copyright© M&Aクラウド ノンブロッキング 処理1 HTTP API Call 処理2 Database 時間 I/O待ちある処理の間に別の処理を実⾏する、 並⾏プログラム

Slide 17

Slide 17 text

Copyright© M&Aクラウド 前提知識はここまで ここからはWebSocketサーバーを実現できる 愉快な仲間を紹介するぜ!

Slide 18

Slide 18 text

Copyright© M&Aクラウド 今回のWebSocketサーバーのレギュレーション 次の仕様を満たすWebSocketサーバーが作れることを期待します。 1. チャットとしてメッセージが送信できる 2. その他のWebSocketに接続されているクライアントに、別のクライアントの メッセージがサーバーから送信される 作るもの:超簡易的チャット

Slide 19

Slide 19 text

Copyright© M&Aクラウド Ratchet

Slide 20

Slide 20 text

Copyright© M&Aクラウド Ratchet https://github.com/ratchetphp/Ratchet RatchetはPHP⽤のWebSocketライブラリで、リアルタイムのWebアプリケーショ ンを構築するために使⽤されます。 ReactPHPをベースにノンブロッキングI/Oを実現しています。 v0.1のタグが切られたのが2012年5⽉12⽇

Slide 21

Slide 21 text

Copyright© M&Aクラウド Ratchet

Slide 22

Slide 22 text

Copyright© M&Aクラウド Ratchet ReactPHP https://reactphp.org リアクターパターンを⽤いたイベント駆動により、ノンブロッキングI/OをPHPで 実現しているライブラリ。 ReactPHPはイベントループを利⽤しており、⼊出⼒ストリームやタイマー、シグ ナルなどを使って、リアクターパターンで実現されます。これは、Node.js や Twisted(Python)、EventMachine(Ruby)に似た仕組みです。 https://reactphp.org/event-loop/

Slide 23

Slide 23 text

Copyright© M&Aクラウド イベントループの概念 Event Event Event Event Event Event Database File System Network … … … 完了したものが戻る 完了を待たずに次々に実⾏ Response Request Event Queue Thread Pool/ Worker Thread Event Loop

Slide 24

Slide 24 text

Copyright© M&Aクラウド Ratchet コード例(server.php)

Slide 25

Slide 25 text

Copyright© M&Aクラウド Ratchet コード例(server.php) WsServerに渡す処理を時前で実装する

Slide 26

Slide 26 text

Copyright© M&Aクラウド Ratchet コード例(Chat Class)

Slide 27

Slide 27 text

Copyright© M&Aクラウド Ratchet コード例(Chat Class)

Slide 28

Slide 28 text

Copyright© M&Aクラウド Ratchet コード例(Chat Class)

Slide 29

Slide 29 text

Copyright© M&Aクラウド Ratchet WebSocketサーバーの動作確認

Slide 30

Slide 30 text

Copyright© M&Aクラウド AMPHP

Slide 31

Slide 31 text

Copyright© M&Aクラウド https://github.com/amphp/amp AMPHP(Asynchronous Multitasking PHP)はPHP8.1から実装されたFiberを ベースに⾮同期処理を実現しています。Fiberは軽量スレッド(コルーチン)の⼀ 種で、スレッドやプロセスとは異なり、軽量な並列処理を提供します。 また、AMPHPはRevolteというイベントループライブラリを利⽤し、並列処理やス ケジュールが⾏われています。

Slide 32

Slide 32 text

Copyright© M&Aクラウド AMPHP コルーチン コルーチン(coroutine)は、「⼀時停⽌」や 「再開」ができる関数の⼀種で、⾮同期処理や並 ⾏処理を簡潔に書くための仕組みです。 普通の関数とは異なり、実⾏を途中で中断し、後 から続きから再開することができます。

Slide 33

Slide 33 text

Copyright© M&Aクラウド AMPHP AMPHPについて詳しく知りたい⽅はやまゆさんのスライドおすすめです。 https://speakerdeck.com/myamagishi/da-jie-pou-amphpwoshi-tutefei-tong-qi-php-woshi-xian-siyou

Slide 34

Slide 34 text

Copyright© M&Aクラウド AMPHP コード例(server.php)

Slide 35

Slide 35 text

Copyright© M&Aクラウド AMPHP コード例(server.php)

Slide 36

Slide 36 text

Copyright© M&Aクラウド AMPHP コード例(server.php)

Slide 37

Slide 37 text

Copyright© M&Aクラウド AMPHP WebSocketサーバーの動作確認

Slide 38

Slide 38 text

Copyright© M&Aクラウド Workerman

Slide 39

Slide 39 text

Copyright© M&Aクラウド Workerman https://www.workerman.net Workermanは、PHPで書かれた⾼性能な⾮同期イベント駆動型ソケットフレームワークで す。純粋なPHPで実装されており、HTTP、WebSocket、SSL、その他のカスタムプロトコルを サポートしています。 WorkermanはNginxに似ており、以下の要素で構成されています。 1. マルチプロセス(複数のワーカープロセスで並⾏処理) 2. ノンブロッキングI/O 3. イベントループ 技術的にはReactPHPに似ていて、stream_select関数でI/Oを多重化している。

Slide 40

Slide 40 text

Copyright© M&Aクラウド Workerman コード例(server.php)

Slide 41

Slide 41 text

Copyright© M&Aクラウド Workerman コード例(server.php)

Slide 42

Slide 42 text

Copyright© M&Aクラウド Workerman コード例(server.php)

Slide 43

Slide 43 text

Copyright© M&Aクラウド Workerman コード例(server.php)

Slide 44

Slide 44 text

Copyright© M&Aクラウド Workerman コード例(server.php)

Slide 45

Slide 45 text

Copyright© M&Aクラウド Workerman 今回のコードのアーキテクチャ クライアント クライアント Gateway:8082 Gateway:8082 Gateway:8082 Gateway:8082 Business Worker Business Worker Register:1236 RegisterがGatewayやBusinessWorker を管理する

Slide 46

Slide 46 text

Copyright© M&Aクラウド Workerman WebSocketサーバーの動作確認

Slide 47

Slide 47 text

Copyright© M&Aクラウド RoadRunner

Slide 48

Slide 48 text

Copyright© M&Aクラウド https://roadrunner.dev RoadRunnerは、Go⾔語で書かれた⾼性能なPHPアプリケーションサーバーです。 特徴としては、 ● ⾼性能 ○ PHPワーカープロセスを常駐させることでbootstrap処理を削減 ● マルチプロトコル対応 ○ HTTP、gRPC、TCPなどをサポート ● プラグインアーキテクチャ ○ 機能を拡張可能なプラグインシステム ● メモリ効率 ○ ワーカープロセスの再利⽤でメモリ使⽤量を最適化

Slide 49

Slide 49 text

Copyright© M&Aクラウド RoadRunner 結論から⾔うと、要件を満たすWebSocketサーバーは作れませんでし た。 v2系まではspiral/roadrunner-broadcastを利⽤することで、クライアント間のデータを相互に やり取りできたみたいなんですが、現⾏のバージョンではこのライブラリが使えません。 CentrifugeというGo製のWebSocketサーバーと連携するroadrunner-php/centrifugoを使う ことでWebSocketサーバーのビジネスロジックをPHPで記述することは可能みたいですが、 RoadRunner単体で動かすことはできませんでした。 (実はできるよという情報をお持ちの⽅は懇親会で教えて下さい)

Slide 50

Slide 50 text

Copyright© M&Aクラウド RoadRunner WebSocketサーバーの動作確認

Slide 51

Slide 51 text

Copyright© M&Aクラウド Swoole

Slide 52

Slide 52 text

Copyright© M&Aクラウド https://www.swoole.com Swooleは、C/C++で作られたPHPの拡張モジュールでイベント駆動型の⾮同期処理やコルーチ ンに基づく並列ネットワークエンジンです。 ● ⾼性能: C/C++で実装されたコアエンジンによる⾼速処理 ● ⾮同期処理: イベント駆動型アーキテクチャによる効率的なI/O処理 ● コルーチン: 軽量なコルーチンによる並⾏処理 ● メモリ常駐: プロセスが常駐することによるオーバーヘッドの削減 ● マルチプロトコル対応: HTTP、WebSocket、TCP、UDP等をサポート

Slide 53

Slide 53 text

Copyright© M&Aクラウド Swoole ちなみに、Swooleコミュニティで諸々あって枝分かれし、OpenSwooleというフォークがコ ミュニティ主体で開発されています。特に意味はないが今回はOpenSwooleを使いました。 (多分使い⽅は同じだと思われます)

Slide 54

Slide 54 text

Copyright© M&Aクラウド Swoole コード例(server.php)

Slide 55

Slide 55 text

Copyright© M&Aクラウド Swoole コード例(server.php)

Slide 56

Slide 56 text

Copyright© M&Aクラウド Swoole コード例(server.php)

Slide 57

Slide 57 text

Copyright© M&Aクラウド Swoole コード例(server.php)

Slide 58

Slide 58 text

Copyright© M&Aクラウド Swoole WebSocketサーバーの動作確認

Slide 59

Slide 59 text

Copyright© M&Aクラウド まとめ 本来ブロッキングであるPHPを、ノンブロッキングで動かしてWebSocketサー バーを構築する⼿段は⼤きく2パターンあることがわかる ● PHPのストリーム関数やFiber等のコルーチンを使ってI/Oを 多重化する(Ratchet/AMPHP/Workerman) ● PHPプログラムを実⾏させる仕組み⾃体を変えてノンブロッ キングにする(Swoole)

Slide 60

Slide 60 text

Copyright© M&Aクラウド まとめ 2025年現在でPHPでWebSocketサーバーを構築するなら ● コンテナ環境ならSwoole ● レンタルサーバーとかならAMPHP がいいんじゃないでしょうか(本番運⽤はしたことないので無責任) 普通にNode.jsやGoでいいと思います

Slide 61

Slide 61 text

Copyright© M&Aクラウド オンラインコミュニティを運営しています 7/1(⽕) 20:00〜オンラインチャット(oVice)にてわいわいやりますのでぜひご参加ください

Slide 62

Slide 62 text

Copyright© M&Aクラウド echo “thanks watching”; ?>