Slide 1

Slide 1 text

 dais-sasa | Yappli, inc. gRPC+ProtocolBuffers    #yappliculture

Slide 2

Slide 2 text

About us #yappliculture

Slide 3

Slide 3 text

dais-sasa • #%!"  ' • Android  •  $&( • MotionLayout #yappliculture

Slide 4

Slide 4 text

dais-sasa • 48*/'0 # %; • Android& • &"!& )7 • ., $&MotionLayout -( :9563   12 + #yappliculture

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

 #yappliculture

Slide 7

Slide 7 text

1.  2. gRPCProtocolBuffers  3. Android !" 4.   5.   6.  #yappliculture

Slide 8

Slide 8 text

 #yappliculture

Slide 9

Slide 9 text

gRPC+ProtocolBuffers #yappliculture

Slide 10

Slide 10 text

•4*)>?$7  ;%  •JSON+10E& "/A5. @6  D8'2  •! #:-<=(9 B gRPC<= 3+F,C  #yappliculture

Slide 11

Slide 11 text

    #yappliculture

Slide 12

Slide 12 text

API"#)*  $&(,    %API'-+   !    #yappliculture

Slide 13

Slide 13 text

 %!$ %!    "#    #yappliculture

Slide 14

Slide 14 text

gRPC ProtocolBuffers  #yappliculture

Slide 15

Slide 15 text

gRPC #yappliculture

Slide 16

Slide 16 text

•Google" RPC    •Protocol Buffers   !  #yappliculture

Slide 17

Slide 17 text

ProtocolBuffers #yappliculture

Slide 18

Slide 18 text

•Google*2  0-(/)  %$"# •.proto"&4 #1+  •(JSON 3 ),' !!. #yappliculture

Slide 19

Slide 19 text

gRPC+ProtocolBuffers      #yappliculture

Slide 20

Slide 20 text

.proto #yappliculture

Slide 21

Slide 21 text

.proto  (Go)) Android (Java) iOS (swiftObjective-C) gRPC  $*'& • $*'&  • (%  !#Entity • (% " !    

Slide 22

Slide 22 text

Android  #yappliculture

Slide 23

Slide 23 text

 #yappliculture

Slide 24

Slide 24 text

build.gradle() buildscript { repositories { jcenter() mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:3.2.1' classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.0' } } #yappliculture

Slide 25

Slide 25 text

build.gradle(app) apply plugin: 'com.google.protobuf' dependencies { ~  ~ def grpc_version = "1.17.1" api "io.grpc:grpc-okhttp:$grpc_version" api "io.grpc:grpc-protobuf-lite:$grpc_version" api "io.grpc:grpc-stub:$grpc_version" api 'javax.annotation:javax.annotation-api:1.3.2' } #yappliculture

Slide 26

Slide 26 text

protobuf { protoc { artifact = "com.google.protobuf:protoc:3.1.0" } plugins { javalite { artifact = "com.google.protobuf:protoc-gen-javalite:3.0.0" } grpc { artifact = "io.grpc:protoc-gen-grpc-java:1.17.1" } } generateProtoTasks { all().each { task -> task.plugins { javalite {} grpc { option 'lite' } } } } } #yappliculture

Slide 27

Slide 27 text

protobuf { protoc { artifact = "com.google.protobuf:protoc:3.1.0" } plugins { javalite { artifact = "com.google.protobuf:protoc-gen-javalite:3.0.0" } grpc { artifact = "io.grpc:protoc-gen-grpc-java:1.17.1" } } generateProtoTasks { all().each { task -> task.plugins { javalite {} grpc { option 'lite' } } } } }   block block.proto      skip #yappliculture

Slide 28

Slide 28 text

protobuf { protoc { artifact = "com.google.protobuf:protoc:3.1.0" } plugins { javalite { artifact = "com.google.protobuf:protoc-gen-javalite:3.0.0" } grpc { artifact = "io.grpc:protoc-gen-grpc-java:1.17.1" } } generateProtoTasks { all().each { task -> task.plugins { javalite {} grpc { option 'lite' } } } } }        path = '/usr/local/bin/protoc’ skip #yappliculture

Slide 29

Slide 29 text

protobuf { protoc { artifact = "com.google.protobuf:protoc:3.1.0" } plugins { javalite { artifact = "com.google.protobuf:protoc-gen-javalite:3.0.0" } grpc { artifact = "io.grpc:protoc-gen-grpc-java:1.17.1" } } generateProtoTasks { all().each { task -> task.plugins { javalite {} grpc { option 'lite' } } } } }  #+&' gRPC   ! $"&'*,  Java ( plugin  )% skip #yappliculture

Slide 30

Slide 30 text

protobuf { protoc { artifact = "com.google.protobuf:protoc:3.1.0" } plugins { javalite { artifact = "com.google.protobuf:protoc-gen-javalite:3.0.0" } grpc { artifact = "io.grpc:protoc-gen-grpc-java:1.17.1" } } generateProtoTasks { all().each { task -> task.plugins { javalite {} grpc { option 'lite' } } } } } grpc block    (grpc-java) skip #yappliculture

Slide 31

Slide 31 text

protobuf { protoc { artifact = "com.google.protobuf:protoc:3.1.0" } plugins { javalite { artifact = "com.google.protobuf:protoc-gen-javalite:3.0.0" } grpc { artifact = "io.grpc:protoc-gen-grpc-java:1.17.1" } } generateProtoTasks { all().each { task -> task.plugins { javalite {} grpc { option 'lite' } } } } } grpc-javaAndroid   javalite blockAndroid   skip #yappliculture

Slide 32

Slide 32 text

protobuf { protoc { artifact = "com.google.protobuf:protoc:3.1.0" } plugins { javalite { artifact = "com.google.protobuf:protoc-gen-javalite:3.0.0" } grpc { artifact = "io.grpc:protoc-gen-grpc-java:1.17.1" } } generateProtoTasks { all().each { task -> task.plugins { javalite {} grpc { option 'lite' } } } } }    all(): protoc .plugins:    option:    skip #yappliculture

Slide 33

Slide 33 text

 build.gradle    •https://qiita.com/kobaken0029/items/8e2945 f6b4ed6a2fa5ae •https://github.com/google/protobuf-gradle- plugin #yappliculture

Slide 34

Slide 34 text

 #yappliculture

Slide 35

Slide 35 text

1. app/src/main/proto.proto   2.    3. app/build/generated/source/proto  #yappliculture

Slide 36

Slide 36 text

syntax = "proto3"; message CreateRequest { enum Sex { INVALID = 0; //  MALE = 1; //  FEMALE = 2; //  } int32 age = 1; //  string name = 2; //  Sex sex = 3; //  } message CreateResponse { User user = 1; // User  } /*  */ service UserService { //   rpc Create(CreateRequest) returns (CreateResponse); /*  */ }  user.proto

Slide 37

Slide 37 text

public final class UserOuterClass { public static final class CreateRequest … { public enum Sex … { INVALID, MALE, FEMALE } private int age_; public int getAge() private String name_; public String getName() private Sex sex_; public Sex getSex() public Builder newBuilder() public Builder toBuilder() public static final class Builder … { public Builder setAge(int value) public Builder setName(String value) public Builder setSex(Sex value) } } }

Slide 38

Slide 38 text

public final class UserServiceGrpc { public static UserServiceBlockingStub newBlockingStub(Channel channel) public static UserServiceFutureStub newFutureStub(Channel channel) public static final class UserServiceBlockingStub … { public CreateResponse create(CreateRequest request) } public static final class UserServiceFutureStub … { public CreateResponse create(CreateRequest request) } } #yappliculture

Slide 39

Slide 39 text

 #yappliculture

Slide 40

Slide 40 text

•$% #) 1. Channel!( 2. Channel" Stub!( 3. Request!( 4. Stub,Request' + *& . -  #   #yappliculture

Slide 41

Slide 41 text

// Channel val channel = ManagedChannelBuilder.forAddress("10.0.2.2", 443) .build() // UserServiceStub val stub = UserServiceGrpc.newBlockingStub(channel) // Request val createRequest = CreateRequest.newBuilder() .setAge(33) .setName("dais-sasa") .setSex(Sex.MALE) .build() //  val createResult = stub.create(createRequest) #yappliculture

Slide 42

Slide 42 text

// Channel)0 val channel = ManagedChannelBuilder.forAddress("10.0.2.2", 443) .build() // UserService Stub)0 val stub = UserServiceGrpc.newBlockingStub(channel); // Request)0 val createRequest = CreateRequest.newBuilder() .setAge(33) .setName(”dais-sasa") .setSex(Sex.MALE) .build(); // +& val createResult = stub.create(createRequest) -#( %0 5  279$"8 ; !    usePlaintext(): http6/& userAgent(agent: String): userAgent9$ 143 *7forTarget(target: String)  "8 .'target !  #, dns:///: skip #yappliculture

Slide 43

Slide 43 text

// Channel $ val channel = ManagedChannelBuilder.forAddress("10.0.2.2", 443) .build() // UserService Stub $ val stub = UserServiceGrpc.newBlockingStub(channel) // Request $ val createRequest = CreateRequest.newBuilder() .setAge(33) .setName(”dais-sasa") .setSex(Sex.MALE) .build(); // " val createResult = stub.create(createRequest); ServiceGrpc  &#!  .proto service block %$ newStub(channel: Cnannel) Stub $()%$) BlockingStub '&# FutureStub ('&# skip #yappliculture

Slide 44

Slide 44 text

// Channel val channel = ManagedChannelBuilder.forAddress("10.0.2.2", 443) .build() // UserServiceStub val stub = UserServiceGrpc.newBlockingStub(channel); // Request val createRequest = CreateRequest.newBuilder() .setAge(33) .setName(”dais-sasa") .setSex(Sex.MALE) .build() //  val createResult = stub.create(createRequest) Entity  .proto  message block skip #yappliculture

Slide 45

Slide 45 text

 #yappliculture

Slide 46

Slide 46 text

   #yappliculture

Slide 47

Slide 47 text

• • •      #yappliculture

Slide 48

Slide 48 text

 skip #yappliculture

Slide 49

Slide 49 text

•Channel Stub&$! # •Channel Stub &   •"%gRPC   skip #yappliculture

Slide 50

Slide 50 text

  skip #yappliculture

Slide 51

Slide 51 text

•#$ !"  & %   Google' (     •    skip #yappliculture

Slide 52

Slide 52 text

      #yappliculture

Slide 53

Slide 53 text

        #yappliculture

Slide 54

Slide 54 text

 #yappliculture

Slide 55

Slide 55 text

API   View   View Class hgadlk;kjralghal;;eur() #yappliculture

Slide 56

Slide 56 text

API $'View&  View+Class& hgadlk;kjralghal;;eur(!,*-#() ("%   )  > Proto) #yappliculture

Slide 57

Slide 57 text

API'"%(",1View0 View!&$7Class0hgadlk;kjralghal;;eur()869+3) (*. )   > Proto# &5 (2:4Java# &-)    …(/)869+3) #yappliculture

Slide 58

Slide 58 text

API)$'*$.4 View3  View#(&:Class3hgadlk;kjralghal;;eur(+;9<-6) (,1  )   > Proto%!"(8 (5=7 Java%!"(0)   …(2+;9<-6) /> #yappliculture

Slide 59

Slide 59 text

API)$'*$.4 View3  View#(&:Class3hgadlk;kjralghal;;eur(+;9<-6) (,1  )   > Proto%!"(8 (5=7 Java%!"(0)   …(2+;9<-6) /> #yappliculture

Slide 60

Slide 60 text

 #yappliculture

Slide 61

Slide 61 text

Y     > protoPR #yappliculture

Slide 62

Slide 62 text

Y0%'35.*    > proto$(PR6  (PR-) !#4 7   > PR12+ &)",/ #yappliculture

Slide 63

Slide 63 text

Y8#+.;>61!    > proto*"$/PR ?  (PR 5) !&)= A > PR9:3%-0( 47 (9:3%-0( 5) OK@2PR9:C

Slide 64

Slide 64 text

Y9$,/=A72"   > proto+#%0PR!B  (PR!6) "'*@ D   > PR:<4&.1)!58 (:<4&.1)!6) OKC3PR:<F>E-(   ;? #yappliculture

Slide 65

Slide 65 text

$&',27B? •.proto *. !)9 A> <- •API )(%+", 15= 3/8@:7  •.proto * #;06  4 #yappliculture

Slide 66

Slide 66 text

   #yappliculture

Slide 67

Slide 67 text

•.proto  %   •API!Entity.proto '   •Android 8.0"TLS&# $& %   #yappliculture

Slide 68

Slide 68 text

.proto      #yappliculture

Slide 69

Slide 69 text

%1, proto- .0&*"5  #3()24 $/' ↓ +!(   24  #yappliculture

Slide 70

Slide 70 text

gRPC.proto$)2<86  '& !";5/# 2</ Ø%(((..proto$)37  41-%(#' ;5 Ø0>:* #'  proto$)+=, ((937   #yappliculture

Slide 71

Slide 71 text

API Entity .proto    #yappliculture

Slide 72

Slide 72 text

!*(  , +   %$ ↓  .- #/ ' "&) #yappliculture

Slide 73

Slide 73 text

 User     #yappliculture

Slide 74

Slide 74 text

Entity user.prof.address.prefectures = "" #yappliculture

Slide 75

Slide 75 text

syntax = “proto3”; message User { Prof prof = 1; //  } message Prof { Address address = 1; //  } message Address { string prefectures = 1; //  } #yappliculture

Slide 76

Slide 76 text

gRPC Entity // Builder  val userBuilder = user.toBuilder() val profBuilder = user.prof.toBuilder() val addressBuilder = user.prof.address.toBuilder() //   addressBuilder.prefectures = "" profBuilder.address = addressBuilder.build() userBuilder.prof = profBuilder.build() // API   userBuilder.build() #yappliculture

Slide 77

Slide 77 text

•gRPC " Entitysetter   •Entity !Builder Builder #$  #yappliculture

Slide 78

Slide 78 text

•%2/ '-:3 •48+1 object 8+* object 7 object  &!#60  %2/ 1$  "( .9    5,) #yappliculture

Slide 79

Slide 79 text

Android 8.0 TLS     #yappliculture

Slide 80

Slide 80 text

)& usePlaintext() $'(%#  ↓   '"  Android 8.0!  #yappliculture

Slide 81

Slide 81 text

•Android 8.0.5&+"*$ (-ALPN3 •%9ALPN;/0  61<7)>  • 4)'! ALPN ,#:2  Android 8.0.5 ?<7) =8  #yappliculture

Slide 82

Slide 82 text

 ALPN      •  !  • No ALPN negotiated $  ALPN     ALPN "# $ openssl s_client -alpn h2 -connect : #yappliculture

Slide 83

Slide 83 text

 #yappliculture

Slide 84

Slide 84 text

•/# 0gRPC *5  ". •$!)4'3 +(1,26 -1& gRPC+ProtocolBuffers *  %  #yappliculture

Slide 85

Slide 85 text

Fin.