Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Request in a QUIC way @shibuya.apk#28
Search
TakuSemba
September 27, 2018
Technology
1.2k
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Request in a QUIC way @shibuya.apk#28
TakuSemba
September 27, 2018
More Decks by TakuSemba
See All by TakuSemba
Customize & Debug ExoPlayer @droidkaigi 2020
takusemba
0
2.1k
Jetpack Compose
takusemba
3
3.7k
Protobuf in Kotlin
takusemba
2
2.1k
Single Activity with MVVM
takusemba
4
1.4k
KotlinConf Report @ca.kt#7
takusemba
2
500
Lint for Kotlin @R.kt#3
takusemba
3
1.6k
Auto Release @potatochips#48
takusemba
1
1.3k
Media streaming on Android @droidkaigi 2018
takusemba
6
8.3k
gRPC on Android @DroidconSF Report
takusemba
1
650
Other Decks in Technology
See All in Technology
Webアクセシビリティ入門 2026
recruitengineers
PRO
3
460
【CEDEC2026】『Relink』を拡張せよ - 『GRANBLUE FANTASY: Relink - Endless Ragnarok』の開発速度と品質を守るCI運用
cygames
PRO
0
140
名刺メーカーDevグループ 紹介資料
sansan33
PRO
0
1.2k
AIエージェントを前提としたプラットフォーム エンジニアリング:GKEで作るAgent-Ready Golden Path
legalontechnologies
PRO
2
220
SO-101×VLAによる3色キューブのピック&プレース
abeja
0
160
サイバー捜査員研修(後半)
nomizone
1
810
システム思考で問題に対処する
yussak
0
210
【Google Cloud Next Tokyo'26】Gemini Enterprise と Oracle AI Database で実現する、業務データ活用を実現する AI エージェント実装
shisyu_gaku
0
230
AWS ネットワーク構築でハマった(ハマりかけた) 5選とそこから得た教訓
nagisa53
4
200
FORENSIA: ローカルLLMフォレンジックハーネス
sumeshi
2
350
Agent 時代の Kaggle 展望 / kaggle-in-the-agentic-era
upura
1
680
修正PRを食べてレビュースキルが賢くなる:Claude Codeによる自己改善サイクル
yuyaumetsu
6
1.4k
Featured
See All Featured
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
230
23k
Self-Hosted WebAssembly Runtime for Runtime-Neutral Checkpoint/Restore in Edge–Cloud Continuum
chikuwait
0
690
Visualization
eitanlees
152
17k
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
2
630
Side Projects
sachag
455
43k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
360
30k
Test your architecture with Archunit
thirion
1
2.3k
Building AI with AI
inesmontani
PRO
1
1.1k
Winning Ecommerce Organic Search in an AI Era - #searchnstuff2025
aleyda
1
2.1k
The Cult of Friendly URLs
andyhume
79
7k
We Have a Design System, Now What?
morganepeng
55
8.3k
Art, The Web, and Tiny UX
lynnandtonic
304
22k
Transcript
None
@takusemba https://github.com/TakuSemba
QUIC?
Quick UDP Internet Connections
QUIC
Google QUIC https://www.chromium.org/quic
QUIC for IETF https://tools.ietf.org/html/draft-hamilton-early-deployment-quic-00
Merits
Merits ɾConnection establishment latency
Connection establishment latency Client Server
Connection establishment latency TCP Client Server
Connection establishment latency TCP Client Server
Connection establishment latency Client Server TCP + TLS
Connection establishment latency TCP + TLS Client Server
Connection establishment latency TCP + TLS Client Server 1-3 roundtrips
Connection establishment latency TCP + TLS Application Data Client Server
1-3 roundtrips
Connection establishment latency QUIC Client Server
Connection establishment latency QUIC Client Server
Connection establishment latency QUIC Client Server 0-1 roundtrips
Connection establishment latency QUIC Application Data Client Server 0-1 roundtrips
Merits ɾConnection establishment latency
Merits ɾConnection establishment latency ɾMultiplexing
Multiplexing TCP Client Server
Multiplexing TCP Client Server
Multiplexing TCP head of line blocking Client Server
Multiplexing QUIC stream 1 stream 2 stream 3 Client Server
Multiplexing QUIC stream 1 stream 2 stream 3 Client Server
Multiplexing QUIC … … stream 1 stream 2 stream 3
Client Server
Merits ɾConnection establishment latency ɾMultiplexing
Merits ɾConnection establishment latency ɾMultiplexing ɾConnection Migration
Connection Migration TCP IP: yyy.yyy.yyy.yyy Port: bb IP: xxx.xxx.xxx.xxx Port:
aa Client Server
Connection Migration TCP IP: yyy.yyy.yyy.yyy Port: bb IP: zzz.zzz.zzz.zzz Port:
cc Client Server
Connection Migration QUIC Connection ID: xxxxxx Connection ID: yyyyyy Client
Server
Connection Migration QUIC Connection ID: xxxxxx Connection ID: yyyyyy Client
Server
Merits ɾConnection establishment latency ɾMultiplexing ɾConnection Migration
Merits ɾConnection establishment latency ɾMultiplexing ɾConnection Migration ɾCongestion Control
Merits ɾConnection establishment latency ɾMultiplexing ɾConnection Migration ɾCongestion Control ɾForward
Error Correction
Cronet
https://developer.android.com/guide/topics/connectivity/cronet
Quicstart
dependencies { implementation "org.chromium.net:cronet-embedded:x.x.x" }
val cronetEngine = CronetEngine.Builder(context) .enableHttp2(true) .enableQuic(true) .build() val request =
cronetEngine.newUrlRequestBuilder(url, callback, executor) .setHttpMethod("GET") .addHeader("hoge", "huga") .build() request.start()
val cronetEngine = CronetEngine.Builder(context) .enableHttp2(true) .enableQuic(true) .build() val request =
cronetEngine.newUrlRequestBuilder(url, callback, executor) .setHttpMethod("GET") .addHeader("hoge", "huga") .build() request.start() .enableQuic(true)
val cronetEngine = CronetEngine.Builder(context) .enableHttp2(true) .enableQuic(true) .build() val request =
cronetEngine.newUrlRequestBuilder(url, callback, executor) .setHttpMethod("GET") .addHeader("hoge", "huga") .build() request.start()
val cronetEngine = CronetEngine.Builder(context) .enableHttp2(true) .enableQuic(true) .build() val request =
cronetEngine.newUrlRequestBuilder(url, callback, executor) .setHttpMethod("GET") .addHeader("hoge", "huga") .build() request.start() newUrlRequestBuilder(url, callback, executor)
val cronetEngine = CronetEngine.Builder(context) .enableHttp2(true) .enableQuic(true) .build() val request =
cronetEngine.newUrlRequestBuilder(url, callback, executor) .setHttpMethod("GET") .addHeader("hoge", "huga") .build() request.start() .setHttpMethod("GET") .addHeader("hoge", "huga")
val cronetEngine = CronetEngine.Builder(context) .enableHttp2(true) .enableQuic(true) .build() val request =
cronetEngine.newUrlRequestBuilder(url, callback, executor) .setHttpMethod("GET") .addHeader("hoge", "huga") .build() request.start()
val cronetEngine = CronetEngine.Builder(context) .enableHttp2(true) .enableQuic(true) .build() val request =
cronetEngine.newUrlRequestBuilder(url, callback, executor) .setHttpMethod("GET") .addHeader("hoge", "huga") .build() request.start()
val cronetEngine = CronetEngine.Builder(context) .enableHttp2(true) .enableQuic(true) .build() val request =
cronetEngine.newUrlRequestBuilder(url, callback, executor) .setHttpMethod("GET") .addHeader("hoge", "huga") .build() request.start() callback
val callback = object : UrlRequest.Callback() { private val bytesReceived
= ByteArrayOutputStream() private val receiveChannel = Channels.newChannel(bytesReceived) override fun onResponseStarted(request: UrlRequest, info: UrlResponseInfo) { // read response request.read(ByteBuffer.allocateDirect(32 * 1024)) } … }
val callback = object : UrlRequest.Callback() { private val bytesReceived
= ByteArrayOutputStream() private val receiveChannel = Channels.newChannel(bytesReceived) override fun onResponseStarted(request: UrlRequest, info: UrlResponseInfo) { // read response request.read(ByteBuffer.allocateDirect(32 * 1024)) } … } override fun onResponseStarted(request: UrlRequest, info: UrlResponseInfo) { // read response request.read(ByteBuffer.allocateDirect(32 * 1024)) }
val callback = object : UrlRequest.Callback() { private val bytesReceived
= ByteArrayOutputStream() private val receiveChannel = Channels.newChannel(bytesReceived) override fun onReadCompleted( request: UrlRequest, info: UrlResponseInfo, byteBuffer: ByteBuffer) { // write response byteBuffer.flip() receiveChannel.write(byteBuffer) // read response byteBuffer.clear() request.read(byteBuffer) } … }
val callback = object : UrlRequest.Callback() { private val bytesReceived
= ByteArrayOutputStream() private val receiveChannel = Channels.newChannel(bytesReceived) override fun onReadCompleted( request: UrlRequest, info: UrlResponseInfo, byteBuffer: ByteBuffer) { // write response byteBuffer.flip() receiveChannel.write(byteBuffer) // read response byteBuffer.clear() request.read(byteBuffer) } … } override fun onReadCompleted( request: UrlRequest, info: UrlResponseInfo, byteBuffer: ByteBuffer) { // write response byteBuffer.flip() receiveChannel.write(byteBuffer) // read response byteBuffer.clear() request.read(byteBuffer) }
val callback = object : UrlRequest.Callback() { private val bytesReceived
= ByteArrayOutputStream() private val receiveChannel = Channels.newChannel(bytesReceived) override fun onReadCompleted( request: UrlRequest, info: UrlResponseInfo, byteBuffer: ByteBuffer) { // write response byteBuffer.flip() receiveChannel.write(byteBuffer) // read response byteBuffer.clear() request.read(byteBuffer) } … } override fun onReadCompleted( byteBuffer: ByteBuffer
val callback = object : UrlRequest.Callback() { private val bytesReceived
= ByteArrayOutputStream() private val receiveChannel = Channels.newChannel(bytesReceived) override fun onReadCompleted( request: UrlRequest, info: UrlResponseInfo, byteBuffer: ByteBuffer) { // write response byteBuffer.flip() receiveChannel.write(byteBuffer) // read response byteBuffer.clear() request.read(byteBuffer) } … } private val receiveChannel = Channels.newChannel(bytesReceived) override fun onReadCompleted( request: UrlRequest, info: UrlResponseInfo, byteBuffer: ByteBuffer) { // write response byteBuffer.flip() receiveChannel.write(byteBuffer) }
val callback = object : UrlRequest.Callback() { private val bytesReceived
= ByteArrayOutputStream() private val receiveChannel = Channels.newChannel(bytesReceived) override fun onReadCompleted( request: UrlRequest, info: UrlResponseInfo, byteBuffer: ByteBuffer) { // write response byteBuffer.flip() receiveChannel.write(byteBuffer) // read response byteBuffer.clear() request.read(byteBuffer) } … } override fun onReadCompleted( request: UrlRequest, info: UrlResponseInfo, byteBuffer: ByteBuffer) { // read response byteBuffer.clear() request.read(byteBuffer) }
val callback = object : UrlRequest.Callback() { private val bytesReceived
= ByteArrayOutputStream() private val receiveChannel = Channels.newChannel(bytesReceived) override fun onReadCompleted( request: UrlRequest, info: UrlResponseInfo, byteBuffer: ByteBuffer) { // write response byteBuffer.flip() receiveChannel.write(byteBuffer) // read response byteBuffer.clear() request.read(byteBuffer) } … } override fun onReadCompleted( request: UrlRequest, info: UrlResponseInfo, byteBuffer: ByteBuffer) { // write response byteBuffer.flip() receiveChannel.write(byteBuffer) // read response byteBuffer.clear() request.read(byteBuffer) }
val callback = object : UrlRequest.Callback() { private val bytesReceived
= ByteArrayOutputStream() private val receiveChannel = Channels.newChannel(bytesReceived) override fun onSucceeded(request: UrlRequest, info: UrlResponseInfo) { // succeeded val result = bytesReceived.toByteArray() } … }
val callback = object : UrlRequest.Callback() { private val bytesReceived
= ByteArrayOutputStream() private val receiveChannel = Channels.newChannel(bytesReceived) override fun onSucceeded(request: UrlRequest, info: UrlResponseInfo) { // succeeded val result = bytesReceived.toByteArray() } … } override fun onSucceeded(request: UrlRequest, info: UrlResponseInfo) { // succeeded val result = bytesReceived.toByteArray() }
val callback = object : UrlRequest.Callback() { private val bytesReceived
= ByteArrayOutputStream() private val receiveChannel = Channels.newChannel(bytesReceived) override fun onFailed(request: UrlRequest, info: UrlResponseInfo, e: CronetException) { // failed Log.d("CRONET_SAMPLE", "failed: ${e.message}") } … } override fun onFailed(request: UrlRequest, info: UrlResponseInfo, e: CronetException) { // failed Log.d("CRONET_SAMPLE", "failed: ${e.message}") }
QUIC for ExoPlayer
https://github.com/google/ExoPlayer/tree/release-v2/extensions/cronet
Client .m3u8 .mp4 .mp4 .ts OkHttp
Client .m3u8 .mp4 .mp4 .ts Cronet
OkHttpClient
val userAgent = "takusemba" val okHttpClient = OkHttpClient() val transferListener
= DefaultBandwidthMeter() val factory = OkHttpDataSourceFactory(okHttpClient, userAgent, transferListener) OkHttpClient
val userAgent = "takusemba" val okHttpClient = OkHttpClient() val transferListener
= DefaultBandwidthMeter() val factory = OkHttpDataSourceFactory(okHttpClient, userAgent, transferListener) OkHttpClient Cronet
val userAgent = "takusemba" val okHttpClient = OkHttpClient() val transferListener
= DefaultBandwidthMeter() val factory = OkHttpDataSourceFactory(okHttpClient, userAgent, transferListener) OkHttpClient val userAgent = "takusemba" val cronetEngine = CronetEngine.Builder(context).enableQuic(true).build() val wrapper = CronetEngineWrapper(cronetEngine) val executor = Executors.newSingleThreadExecutor() val predicate = Predicate { contentType: String -> true } val factory = CronetDataSourceFactory(wrapper, executor, predicate, userAgent) Cronet
val userAgent = "takusemba" val okHttpClient = OkHttpClient() val transferListener
= DefaultBandwidthMeter() val factory = OkHttpDataSourceFactory(okHttpClient, userAgent, transferListener) OkHttpClient val userAgent = "takusemba" val cronetEngine = CronetEngine.Builder(context).enableQuic(true).build() val wrapper = CronetEngineWrapper(cronetEngine) val executor = Executors.newSingleThreadExecutor() val predicate = Predicate { contentType: String -> true } val factory = CronetDataSourceFactory(wrapper, executor, predicate, userAgent) val wrapper = CronetEngineWrapper(cronetEngine) val executor = Executors.newSingleThreadExecutor() val predicate = Predicate { contentType: String -> true } Cronet
val userAgent = "takusemba" val okHttpClient = OkHttpClient() val transferListener
= DefaultBandwidthMeter() val factory = OkHttpDataSourceFactory(okHttpClient, userAgent, transferListener) OkHttpClient Cronet val userAgent = "takusemba" val cronetEngine = CronetEngine.Builder(context).enableQuic(true).build() val wrapper = CronetEngineWrapper(cronetEngine) val executor = Executors.newSingleThreadExecutor() val predicate = Predicate { contentType: String -> true } val factory = CronetDataSourceFactory(wrapper, executor, predicate, userAgent) val factory = CronetDataSourceFactory(wrapper, executor, predicate, userAgent)
None
https://github.com/TakuSemba/QuicPlayer Sample App
https://github.com/takusemba https://twitter.com/takusemba Request in a QUIC way