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
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
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
DGX Sparkを2台使って いろいろ動かす話
sonoda_mj
1
130
Backstageでつくるセルフサービスな社内開発基盤
kikunosuke75
1
340
Nav2、Nav3 ... はたまた自作?〜 作って理解する Nav3 の設計意図 〜 / Nav2, Nav3 ... or Build Your Own? — Understanding Nav3's design intent by building it from scratch
yanzm
0
250
IoTハンズオンの舞台裏
shirouz
2
140
KAEN Company Deck
kaen
PRO
0
320
書籍『生成AIの安全性入門』の入門
wataoka
0
220
AIエージェントの開発・提供におけるセキュリティリスクの論点と対策
flatt_security
1
580
2026-09-04 SRE Tech Talk #15 怠惰なTerraform / Lazy Terraform
masasuzu
0
200
Driving AI Adoption Using In-House GPUs to Serve Qwen
po3rin
2
460
リージョンの壁を越える、 ちょっと変わったAWSサービスの話
falken
PRO
0
260
AIとペアプロを始める。人とのペアプロをやめる。ペアプロの良さを改めて知る。もっと好きになった。 / Rediscovering Pair Programming
honyanya
1
250
プロダクト思考 × 基盤思考を AIで実現する Compound Engineering
tkc66buzz
1
270
Featured
See All Featured
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
17k
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
Game over? The fight for quality and originality in the time of robots
wayneb77
1
260
Making the Leap to Tech Lead
cromwellryan
135
10k
Speed Design
sergeychernyshev
33
2.1k
How People are Using Generative and Agentic AI to Supercharge Their Products, Projects, Services and Value Streams Today
helenjbeal
1
310
Chasing Engaging Ingredients in Design
codingconduct
0
300
HU Berlin: Industrial-Strength Natural Language Processing with spaCy and Prodigy
inesmontani
PRO
0
690
コードの90%をAIが書く世界で何が待っているのか / What awaits us in a world where 90% of the code is written by AI
rkaga
63
45k
How to Align SEO within the Product Triangle To Get Buy-In & Support - #RIMC
aleyda
2
1.8k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
10k
How Software Deployment tools have changed in the past 20 years
geshan
1
34k
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