Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
あえてPHPでリアルタイム通信をやってみる
Search
Miyamoto Naoyuki
June 05, 2026
Technology
390
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
あえてPHPでリアルタイム通信をやってみる
フロントエンド・PHPカンファレンス北海道2026 #frontend_phpcon_do #vaddy_room
Miyamoto Naoyuki
June 05, 2026
More Decks by Miyamoto Naoyuki
See All by Miyamoto Naoyuki
私がブラウザを自作したくなった理由
supurazako
1
300
ビデオ通話が繋がる0.2秒で何が起きているのか
supurazako
2
220
HTTPに新しいMethod! QUERY RFC10008
supurazako
0
35
MinecraftにP2Pが来るぞ!
supurazako
0
98
標準化っていいな〜JANOGでの学び〜
supurazako
0
100
Other Decks in Technology
See All in Technology
20260912_スクフェス三河
kgnkhkr
0
380
人間はどの意思決定を手放せるのか
kawasima
14
6.9k
「守り」で活用するオンデバイスLLM 〜写ってはいけないを総力戦で防ぐ〜 / iOSDC Japan 2026
nakamuuu
0
160
なぜ「決定性」が 決定的に重要なのか? Durable Execution 基盤の数理的理解 #serverlessjp / ServerlessDays Tokyo 2026
ytaka23
0
110
俺の仕事は AIに奪われないし、たぶんその BIも要らない
hikaruri
0
490
事業課題から技術的負債に向き合う
sansantech
PRO
2
1.8k
株式会社シーエーシー エンジニア向け会社紹介資料
cac
0
57k
TinyGo 開発サイクルを高速化する:Go で作るエミュレータ入門
zozotech
PRO
1
740
研究開発部の紹介 / Sansan R&D Profile
sansan33
PRO
5
25k
AIネイティブプロダクトで顧客価値を最大化するプロダクトエンジニアとFDEの協働
righttouch
PRO
0
310
越境するなら専門用語を使うな高校校歌 / If you wanna cross border, you shouldn't use jargon
vtryo
0
140
幾何アルゴリズムで なめらかなピン操作を / iOSDC Japan 2026 / smoothpin
kazumanagano
0
350
Featured
See All Featured
Digital Projects Gone Horribly Wrong (And the UX Pros Who Still Save the Day) - Dean Schuster
uxyall
1
2.9k
Docker and Python
trallard
47
4.2k
Optimizing for Happiness
mojombo
378
71k
Heart Work Chapter 1 - Part 1
lfama
PRO
10
36k
Navigating Team Friction
lara
192
16k
Writing Fast Ruby
sferik
630
63k
Building Adaptive Systems
keathley
44
3.2k
The untapped power of vector embeddings
frankvandijk
2
1.9k
Scaling GitHub
holman
464
140k
How to Align SEO within the Product Triangle To Get Buy-In & Support - #RIMC
aleyda
2
1.8k
How to build an LLM SEO readiness audit: a practical framework
nmsamuel
1
910
Exploring the relationship between traditional SERPs and Gen AI search
raygrieselhuber
PRO
3
4.3k
Transcript
あえてPHPでリアルタイム通信をやってみる 2026-06-06 フロントエンド・PHPカンファレンス北海道2026 宮本直幸@MSprzk
$ cat profile.service [Unit] Description=Self Introduction After=network.target [Profile] Name="Miyamoto Naoyuki"
Twitter="@Msprzk" Affiliation="北海道情報大学2年" Interest="Network",”Security”,”WebRTC”
None
北海道のおすすめのところ
伝えたいこと PHPは、リアルタイム通信ができないわけではない
きっかけ
←WebSocket, WebRTCが大好き ←PHPはTODOアプリを作ったことがあるくらい
PHPでもリアルタイム通信をできるのかな? 調べてみたらあんまり得意ではなさそう...
PHPでもリアルタイム通信をできるのかな? 調べてみたらあんまり得意ではなさそう... やってみなくちゃわからない
そもそもリアルタイム通信とは
遅延が少なく、ほぼリアルタイムで通信すること(厳密な定義は不明) 通話、ビデオ会議、オンラインゲームなどで使われることが多い リアルタイム通信技術の例: WebSocket, WebRTC, etc… リアルタイム通信とは
検証の環境 バージョンと環境 - MacBook Air M2 - Memory 8GB -
PHP: 8.5.6 - Go: 1.26.3 - Node.js: v26.0.0
検証方法 - PHP / TypeScript / Go でWebSocket relayを実装 -
動画を送信し、20のreceiverにrelayする - 送信は基本的にPlaywrightのheadless(GUI付きとあまり変わらない結果 だったので、全てheadlessで撮り直しました) - 各実装ごとに10回実行 - 実行順による偏りを避けるため、ランダムな順番で実行 - 各実行ごとにp95, p99, max latency, loss, append error を計測 - 比較値は主に10回の実行の median p95, p99 = 遅延分布の95%, 99%地点. 99%地点が悪いほど、まれに大きくつまっているということ
UI使ったバージョン
実験結果
単一プロセスの場合 実装 loss append error 受信側p99 遅延 サーバ側 p99遅延 評価
TS 0 0 15.05ms 3.00ms 成立 PHP 0 0 61.95ms 19.50ms 成立 Go 0 0 24.80ms 5.50ms 成立 ※ p99: 遅延分布の99%地点。数値は10回実行した中央値。 ※ 受信側 p99 遅延: 各receiverのp99を平均した値。
そんなことあるか? PHPの仕様について調べてみよう
PHPの強み →Web向けサーバーサイドスクリプト →短命のHTTP処理が得意 →通常のWeb Page, API処理では強み PHPの仕様
リアルタイム通信で必要な性質 →短命ではなく長命のconnection →slow receiverの影響を他receiverから隔離する →receiver ごとの queue を持つ PHPの仕様
リアルタイム通信で必要な性質 →短命ではなく長命のconnection →slow receiverの影響を他receiverから隔離する →receiver ごとの queue を持つ PHPの仕様 仮説:
PHP(FPM)の強みは、リアルタイム通信では 相性が良くないはず
単一プロセスで動くものは少ないよね... Node.jsのような, PHPの代表的な 実行環境について調べてみよう
PHP-FPM: PHPのWeb実行環境 PHP-FPM
PHP-FPM: PHPのWeb実行環境 PHP-FPM
PHP-FPM
検証内容: 長命WebSocket接続がreadyになるまでの待ち時間 Clients: 6 maxWorkers: 2 Hold: 10秒 ※maxWorkersは、workerの占有をわかりやすくするために意図的に低い上限にしています ※Hold
→ 接続を張ったあと、その接続を保持し続ける時間 PHP-FPM(風)
PHP-FPM(風) 実装 モデル ready p50 ready p99 評価 php-process-pool FPM的worker
pool 10112.00ms 20218.50ms 後続接続が待 たされる ts-native Node.js event loop 4.00ms 9.00ms ほぼ同時 go-native Go goroutine 4.00ms 14.00ms ほぼ同時
なぜ待たされるのか 長命接続が worker を占有する ↓ worker 数を超えた接続は ready になる前に待たされる
1. 接続を変える場所 - 長命接続をどの実行モデルで持つか - FPM風 worker poolでは、connectionがworkerを占有 2. 接続後に送る場所
- 接続済みreceiverにどう配信するか - 遅いreceiverの影響を他receiverに波及させないか リアルタイム通信で詰まる場所は2つある
FPM風 worker poolから外しても、リアルタイム通信の難しさは消 えるわけではない 接続済み receiverに動画を送る時、遅い(回線の悪い)receiverが いると、他receiverに波及する可能性がある →同じPHPの単一常駐プロセス内で、送信設計を変えて比較 単一常駐プロセス内の送信設計
FPM風 worker poolから外しても、リアルタイム通信の難しさは消 えるわけではない 接続済み receiverに動画を送る時、遅い(回線の悪い)receiverが いると、他receiverに波及する可能性がある →同じPHPの単一常駐プロセス内で、送信設計を変えて比較 単一常駐プロセス内の送信設計
php-ws php-ws-queued 順番に送る 書けるものから 書く
実装 送信設計 受信側p99 サーバー側p99 通常receiver p99 評価 php-ws 全receiverへ同 期write
95.90ms 13.00ms 86.49ms 波及しやすい php-ws-queued receiverごとの write buffer 46.67ms 3.00ms 27.12ms 波及が減る
- FPM風 worker poolの問題は、長命接続をどこで抱えるかという 実行モデルの問題 - Queued での問題は、接続後にどう送るかという送信設計の問題 つまり、PHPでリアルタイム通信をやるなら、 -
FPM的な request/response モデルから外す - 常駐サーバー内で receiver ごとの queue / backpressure を設計する という2段階の設計が必要になる ここから言えること
- PHPでのリアルタイム通信は不可能ではない - 単一の常駐プロセスとしては、普通に動く - ただし、PHP-FPMのようなWeb実行モデルは、長命接続を大量に抱える 設計になっていない - FPMから外しても、 queue,
backpressure の設計は必要 - PHPでリアルタイム通信をやるには、常駐サーバと送信制御を明示的に設計 する必要がある 結論
伝えたいこと PHPは、リアルタイム通信ができないわけではない
PHP Manual: FastCGI Process Manager (FPM) https://www.php.net/manual/en/install.fpm.php PHP Manual: FPM
Configuration https://www.php.net/manual/en/install.fpm.configuratio n.php 参考
https://github.com/supurazako/php-realtime
UDP版も作ってみましたが、 - protocolの違いは本質ではなかった - 送られる映像がガビガビ & 遅延が酷すぎる - 上記の問題を解決するための実装はあまりにも重すぎる ↑の理由から説明しませんでした
おまけ: UDP版も作ってみたが...